summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt31
-rw-r--r--Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt36
-rw-r--r--Documentation/devicetree/bindings/mips/lantiq/rcu.txt89
-rw-r--r--Documentation/devicetree/bindings/mips/ni.txt7
-rw-r--r--Documentation/devicetree/bindings/mips/ralink.txt1
-rw-r--r--Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt40
-rw-r--r--Documentation/devicetree/bindings/reset/lantiq,reset.txt30
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt24
-rw-r--r--MAINTAINERS21
-rw-r--r--arch/mips/Kconfig21
-rw-r--r--arch/mips/Makefile31
-rw-r--r--arch/mips/alchemy/devboards/db1200.c64
-rw-r--r--arch/mips/alchemy/devboards/db1300.c31
-rw-r--r--arch/mips/alchemy/devboards/db1xxx.c2
-rw-r--r--arch/mips/ar7/clock.c3
-rw-r--r--arch/mips/ath79/clock.c9
-rw-r--r--arch/mips/bcm63xx/clk.c3
-rw-r--r--arch/mips/boot/Makefile16
-rw-r--r--arch/mips/boot/dts/Makefile1
-rw-r--r--arch/mips/boot/dts/ingenic/ci20.dts37
-rw-r--r--arch/mips/boot/dts/ingenic/jz4780.dtsi11
-rw-r--r--arch/mips/boot/dts/ni/169445.dts100
-rw-r--r--arch/mips/boot/dts/ni/Makefile7
-rw-r--r--arch/mips/boot/dts/ralink/Makefile2
-rw-r--r--arch/mips/boot/dts/ralink/mt7628a.dtsi126
-rw-r--r--arch/mips/boot/dts/ralink/omega2p.dts18
-rw-r--r--arch/mips/boot/dts/ralink/vocore2.dts18
-rw-r--r--arch/mips/cavium-octeon/executive/Makefile2
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-boot-vector.c167
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-bootmem.c85
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c9
-rw-r--r--arch/mips/cavium-octeon/smp.c14
-rw-r--r--arch/mips/configs/cavium_octeon_defconfig25
-rw-r--r--arch/mips/configs/ci20_defconfig3
-rw-r--r--arch/mips/configs/generic/board-ni169445.config30
-rw-r--r--arch/mips/configs/generic/board-sead-3.config2
-rw-r--r--arch/mips/configs/generic_defconfig3
-rw-r--r--arch/mips/configs/gpr_defconfig4
-rw-r--r--arch/mips/configs/lemote2f_defconfig1
-rw-r--r--arch/mips/configs/malta_defconfig1
-rw-r--r--arch/mips/configs/malta_kvm_defconfig1
-rw-r--r--arch/mips/configs/malta_kvm_guest_defconfig1
-rw-r--r--arch/mips/configs/maltasmvp_defconfig1
-rw-r--r--arch/mips/configs/maltasmvp_eva_defconfig1
-rw-r--r--arch/mips/configs/mtx1_defconfig4
-rw-r--r--arch/mips/configs/nlm_xlp_defconfig1
-rw-r--r--arch/mips/configs/nlm_xlr_defconfig4
-rw-r--r--arch/mips/configs/omega2p_defconfig129
-rw-r--r--arch/mips/configs/pistachio_defconfig5
-rw-r--r--arch/mips/configs/vocore2_defconfig129
-rw-r--r--arch/mips/fw/arc/init.c2
-rw-r--r--arch/mips/generic/Kconfig6
-rw-r--r--arch/mips/generic/Platform4
-rw-r--r--arch/mips/generic/board-boston.its.S22
-rw-r--r--arch/mips/generic/board-ni169445.its.S22
-rw-r--r--arch/mips/generic/init.c5
-rw-r--r--arch/mips/generic/irq.c9
-rw-r--r--arch/mips/generic/vmlinux.its.S25
-rw-r--r--arch/mips/include/asm/asm.h3
-rw-r--r--arch/mips/include/asm/bmips.h4
-rw-r--r--arch/mips/include/asm/cpu-info.h62
-rw-r--r--arch/mips/include/asm/cpu-type.h5
-rw-r--r--arch/mips/include/asm/cpu.h5
-rw-r--r--arch/mips/include/asm/floppy.h4
-rw-r--r--arch/mips/include/asm/fpu_emulator.h118
-rw-r--r--arch/mips/include/asm/io.h2
-rw-r--r--arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h26
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h2
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h6
-rw-r--r--arch/mips/include/asm/mach-ip27/topology.h1
-rw-r--r--arch/mips/include/asm/mach-lantiq/lantiq.h2
-rw-r--r--arch/mips/include/asm/mach-loongson64/loongson.h2
-rw-r--r--arch/mips/include/asm/mach-loongson64/topology.h1
-rw-r--r--arch/mips/include/asm/mips-boards/maltaint.h5
-rw-r--r--arch/mips/include/asm/mips-cm.h567
-rw-r--r--arch/mips/include/asm/mips-cpc.h177
-rw-r--r--arch/mips/include/asm/mips-cps.h240
-rw-r--r--arch/mips/include/asm/mips-gic.h347
-rw-r--r--arch/mips/include/asm/mipsregs.h13
-rw-r--r--arch/mips/include/asm/module.h2
-rw-r--r--arch/mips/include/asm/netlogic/common.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-boot-vector.h53
-rw-r--r--arch/mips/include/asm/octeon/cvmx-bootmem.h28
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ciu-defs.h10
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h28
-rw-r--r--arch/mips/include/asm/octeon/octeon.h2
-rw-r--r--arch/mips/include/asm/smp-ops.h16
-rw-r--r--arch/mips/include/asm/smp.h10
-rw-r--r--arch/mips/include/asm/stackframe.h280
-rw-r--r--arch/mips/include/asm/stacktrace.h64
-rw-r--r--arch/mips/include/asm/topology.h2
-rw-r--r--arch/mips/include/uapi/asm/inst.h2
-rw-r--r--arch/mips/kernel/Makefile14
-rw-r--r--arch/mips/kernel/cps-vec.S4
-rw-r--r--arch/mips/kernel/cpu-probe.c59
-rw-r--r--arch/mips/kernel/genex.S13
-rw-r--r--arch/mips/kernel/idle.c1
-rw-r--r--arch/mips/kernel/mips-cm.c94
-rw-r--r--arch/mips/kernel/mips-cpc.c17
-rw-r--r--arch/mips/kernel/mips-r2-to-r6-emul.c16
-rw-r--r--arch/mips/kernel/octeon_switch.S11
-rw-r--r--arch/mips/kernel/pm-cps.c17
-rw-r--r--arch/mips/kernel/proc.c6
-rw-r--r--arch/mips/kernel/process.c102
-rw-r--r--arch/mips/kernel/r2300_fpu.S80
-rw-r--r--arch/mips/kernel/r2300_switch.S81
-rw-r--r--arch/mips/kernel/r4k_fpu.S196
-rw-r--r--arch/mips/kernel/r4k_switch.S203
-rw-r--r--arch/mips/kernel/r6000_fpu.S99
-rw-r--r--arch/mips/kernel/smp-bmips.c10
-rw-r--r--arch/mips/kernel/smp-cmp.c6
-rw-r--r--arch/mips/kernel/smp-cps.c152
-rw-r--r--arch/mips/kernel/smp-mt.c14
-rw-r--r--arch/mips/kernel/smp-up.c5
-rw-r--r--arch/mips/kernel/smp.c24
-rw-r--r--arch/mips/kernel/time.c14
-rw-r--r--arch/mips/kernel/traps.c29
-rw-r--r--arch/mips/kernel/unaligned.c2
-rw-r--r--arch/mips/kernel/vdso.c15
-rw-r--r--arch/mips/lantiq/Kconfig2
-rw-r--r--arch/mips/lantiq/falcon/reset.c23
-rw-r--r--arch/mips/lantiq/irq.c4
-rw-r--r--arch/mips/lantiq/prom.c2
-rw-r--r--arch/mips/lantiq/xway/Makefile4
-rw-r--r--arch/mips/lantiq/xway/reset.c387
-rw-r--r--arch/mips/lantiq/xway/sysctrl.c83
-rw-r--r--arch/mips/lantiq/xway/xrx200_phy_fw.c113
-rw-r--r--arch/mips/lib/Makefile2
-rw-r--r--arch/mips/lib/delay.c1
-rw-r--r--arch/mips/lib/iomap_copy.c42
-rw-r--r--arch/mips/loongson64/lemote-2f/clock.c3
-rw-r--r--arch/mips/loongson64/loongson-3/smp.c16
-rw-r--r--arch/mips/math-emu/Makefile6
-rw-r--r--arch/mips/math-emu/cp1emu.c284
-rw-r--r--arch/mips/math-emu/dp_fmax.c84
-rw-r--r--arch/mips/math-emu/dp_fmin.c86
-rw-r--r--arch/mips/math-emu/dp_maddf.c246
-rw-r--r--arch/mips/math-emu/dp_rint.c89
-rw-r--r--arch/mips/math-emu/ieee754.h2
-rw-r--r--arch/mips/math-emu/ieee754int.h4
-rw-r--r--arch/mips/math-emu/ieee754sp.h4
-rw-r--r--arch/mips/math-emu/me-debugfs.c318
-rw-r--r--arch/mips/math-emu/sp_fmax.c84
-rw-r--r--arch/mips/math-emu/sp_fmin.c86
-rw-r--r--arch/mips/math-emu/sp_maddf.c229
-rw-r--r--arch/mips/math-emu/sp_rint.c90
-rw-r--r--arch/mips/mm/c-r4k.c2
-rw-r--r--arch/mips/mm/cache.c2
-rw-r--r--arch/mips/mm/dma-default.c46
-rw-r--r--arch/mips/mm/init.c1
-rw-r--r--arch/mips/mm/mmap.c1
-rw-r--r--arch/mips/mm/sc-mips.c47
-rw-r--r--arch/mips/mm/tlbex-fault.S7
-rw-r--r--arch/mips/mm/tlbex.c5
-rw-r--r--arch/mips/mti-malta/malta-dtshim.c4
-rw-r--r--arch/mips/mti-malta/malta-init.c3
-rw-r--r--arch/mips/mti-malta/malta-int.c5
-rw-r--r--arch/mips/mti-malta/malta-setup.c4
-rw-r--r--arch/mips/mti-malta/malta-time.c26
-rw-r--r--arch/mips/netlogic/common/smp.c8
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c4
-rw-r--r--arch/mips/paravirt/paravirt-smp.c5
-rw-r--r--arch/mips/paravirt/setup.c2
-rw-r--r--arch/mips/pci/pci-legacy.c2
-rw-r--r--arch/mips/pci/pci-malta.c6
-rw-r--r--arch/mips/pci/pci-mt7620.c2
-rw-r--r--arch/mips/pci/pci-rt3883.c11
-rw-r--r--arch/mips/pistachio/init.c3
-rw-r--r--arch/mips/pistachio/irq.c1
-rw-r--r--arch/mips/pistachio/time.c2
-rw-r--r--arch/mips/ralink/Kconfig10
-rw-r--r--arch/mips/ralink/clk.c3
-rw-r--r--arch/mips/ralink/irq-gic.c2
-rw-r--r--arch/mips/ralink/mt7621.c5
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c5
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c5
-rw-r--r--arch/mips/sibyte/common/cfe.c4
-rw-r--r--arch/mips/sibyte/sb1250/smp.c5
-rwxr-xr-xarch/mips/tools/generic-board-config.sh90
-rw-r--r--arch/mips/vdso/gettimeofday.c8
-rw-r--r--arch/mips/vdso/sigreturn.S10
-rw-r--r--drivers/clocksource/mips-gic-timer.c37
-rw-r--r--drivers/cpuidle/cpuidle-cps.c2
-rw-r--r--drivers/irqchip/irq-mips-cpu.c2
-rw-r--r--drivers/irqchip/irq-mips-gic.c616
-rw-r--r--drivers/mtd/maps/lantiq-flash.c6
-rw-r--r--drivers/pcmcia/db1xxx_ss.c33
-rw-r--r--drivers/phy/Kconfig1
-rw-r--r--drivers/phy/Makefile2
-rw-r--r--drivers/phy/lantiq/Kconfig9
-rw-r--r--drivers/phy/lantiq/Makefile1
-rw-r--r--drivers/phy/lantiq/phy-lantiq-rcu-usb2.c254
-rw-r--r--drivers/reset/Kconfig6
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-lantiq.c212
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/lantiq/Makefile2
-rw-r--r--drivers/soc/lantiq/fpi-bus.c87
-rw-r--r--drivers/soc/lantiq/gphy.c260
-rw-r--r--drivers/watchdog/lantiq_wdt.c74
-rw-r--r--drivers/watchdog/octeon-wdt-main.c354
-rw-r--r--drivers/watchdog/octeon-wdt-nmi.S42
-rw-r--r--include/dt-bindings/mips/lantiq_rcu_gphy.h15
-rw-r--r--include/linux/irqchip/mips-gic.h297
205 files changed, 6399 insertions, 3427 deletions
diff --git a/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt b/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt
new file mode 100644
index 000000000000..0a2df4338332
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt
@@ -0,0 +1,31 @@
1Lantiq XWAY SoC FPI BUS binding
2============================
3
4
5-------------------------------------------------------------------------------
6Required properties:
7- compatible : Should be one of
8 "lantiq,xrx200-fpi"
9- reg : The address and length of the XBAR
10 configuration register.
11 Address and length of the FPI bus itself.
12- lantiq,rcu : A phandle to the RCU syscon
13- lantiq,offset-endianness : Offset of the endianness configuration
14 register
15
16-------------------------------------------------------------------------------
17Example for the FPI on the xrx200 SoCs:
18 fpi@10000000 {
19 compatible = "lantiq,xrx200-fpi";
20 ranges = <0x0 0x10000000 0xf000000>;
21 reg = <0x1f400000 0x1000>,
22 <0x10000000 0xf000000>;
23 lantiq,rcu = <&rcu0>;
24 lantiq,offset-endianness = <0x4c>;
25 #address-cells = <1>;
26 #size-cells = <1>;
27
28 gptu@e100a00 {
29 ......
30 };
31 };
diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt
new file mode 100644
index 000000000000..a0c19bd1ce66
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt
@@ -0,0 +1,36 @@
1Lantiq XWAY SoC GPHY binding
2============================
3
4This binding describes a software-defined ethernet PHY, provided by the RCU
5module on newer Lantiq XWAY SoCs (xRX200 and newer).
6
7-------------------------------------------------------------------------------
8Required properties:
9- compatible : Should be one of
10 "lantiq,xrx200a1x-gphy"
11 "lantiq,xrx200a2x-gphy"
12 "lantiq,xrx300-gphy"
13 "lantiq,xrx330-gphy"
14- reg : Addrress of the GPHY FW load address register
15- resets : Must reference the RCU GPHY reset bit
16- reset-names : One entry, value must be "gphy" or optional "gphy2"
17- clocks : A reference to the (PMU) GPHY clock gate
18
19Optional properties:
20- lantiq,gphy-mode : GPHY_MODE_GE (default) or GPHY_MODE_FE as defined in
21 <dt-bindings/mips/lantiq_xway_gphy.h>
22
23
24-------------------------------------------------------------------------------
25Example for the GPHys on the xRX200 SoCs:
26
27#include <dt-bindings/mips/lantiq_rcu_gphy.h>
28 gphy0: gphy@20 {
29 compatible = "lantiq,xrx200a2x-gphy";
30 reg = <0x20 0x4>;
31
32 resets = <&reset0 31 30>, <&reset1 7 7>;
33 reset-names = "gphy", "gphy2";
34 clocks = <&pmu0 XRX200_PMU_GATE_GPHY>;
35 lantiq,gphy-mode = <GPHY_MODE_GE>;
36 };
diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt
new file mode 100644
index 000000000000..a086f1e1cdd7
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt
@@ -0,0 +1,89 @@
1Lantiq XWAY SoC RCU binding
2===========================
3
4This binding describes the RCU (reset controller unit) multifunction device,
5where each sub-device has it's own set of registers.
6
7The RCU register range is used for multiple purposes. Mostly one device
8uses one or multiple register exclusively, but for some registers some
9bits are for one driver and some other bits are for a different driver.
10With this patch all accesses to the RCU registers will go through
11syscon.
12
13
14-------------------------------------------------------------------------------
15Required properties:
16- compatible : The first and second values must be:
17 "lantiq,xrx200-rcu", "simple-mfd", "syscon"
18- reg : The address and length of the system control registers
19
20
21-------------------------------------------------------------------------------
22Example of the RCU bindings on a xRX200 SoC:
23 rcu0: rcu@203000 {
24 compatible = "lantiq,xrx200-rcu", "simple-mfd", "syscon";
25 reg = <0x203000 0x100>;
26 ranges = <0x0 0x203000 0x100>;
27 big-endian;
28
29 gphy0: gphy@20 {
30 compatible = "lantiq,xrx200a2x-gphy";
31 reg = <0x20 0x4>;
32
33 resets = <&reset0 31 30>, <&reset1 7 7>;
34 reset-names = "gphy", "gphy2";
35 lantiq,gphy-mode = <GPHY_MODE_GE>;
36 };
37
38 gphy1: gphy@68 {
39 compatible = "lantiq,xrx200a2x-gphy";
40 reg = <0x68 0x4>;
41
42 resets = <&reset0 29 28>, <&reset1 6 6>;
43 reset-names = "gphy", "gphy2";
44 lantiq,gphy-mode = <GPHY_MODE_GE>;
45 };
46
47 reset0: reset-controller@10 {
48 compatible = "lantiq,xrx200-reset";
49 reg = <0x10 4>, <0x14 4>;
50
51 #reset-cells = <2>;
52 };
53
54 reset1: reset-controller@48 {
55 compatible = "lantiq,xrx200-reset";
56 reg = <0x48 4>, <0x24 4>;
57
58 #reset-cells = <2>;
59 };
60
61 usb_phy0: usb2-phy@18 {
62 compatible = "lantiq,xrx200-usb2-phy";
63 reg = <0x18 4>, <0x38 4>;
64 status = "disabled";
65
66 resets = <&reset1 4 4>, <&reset0 4 4>;
67 reset-names = "phy", "ctrl";
68 #phy-cells = <0>;
69 };
70
71 usb_phy1: usb2-phy@34 {
72 compatible = "lantiq,xrx200-usb2-phy";
73 reg = <0x34 4>, <0x3C 4>;
74 status = "disabled";
75
76 resets = <&reset1 5 4>, <&reset0 4 4>;
77 reset-names = "phy", "ctrl";
78 #phy-cells = <0>;
79 };
80
81 reboot@10 {
82 compatible = "syscon-reboot";
83 reg = <0x10 4>;
84
85 regmap = <&rcu0>;
86 offset = <0x10>;
87 mask = <0x40000000>;
88 };
89 };
diff --git a/Documentation/devicetree/bindings/mips/ni.txt b/Documentation/devicetree/bindings/mips/ni.txt
new file mode 100644
index 000000000000..722bf2d62da9
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/ni.txt
@@ -0,0 +1,7 @@
1National Instruments MIPS platforms
2
3required root node properties:
4 - compatible: must be "ni,169445"
5
6CPU Nodes
7 - compatible: must be "mti,mips14KEc"
diff --git a/Documentation/devicetree/bindings/mips/ralink.txt b/Documentation/devicetree/bindings/mips/ralink.txt
index b35a8d04f8b6..a16e8d7fe56c 100644
--- a/Documentation/devicetree/bindings/mips/ralink.txt
+++ b/Documentation/devicetree/bindings/mips/ralink.txt
@@ -15,3 +15,4 @@ value must be one of the following values:
15 ralink,rt5350-soc 15 ralink,rt5350-soc
16 ralink,mt7620a-soc 16 ralink,mt7620a-soc
17 ralink,mt7620n-soc 17 ralink,mt7620n-soc
18 ralink,mt7628a-soc
diff --git a/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
new file mode 100644
index 000000000000..643948b6b576
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
@@ -0,0 +1,40 @@
1Lantiq XWAY SoC RCU USB 1.1/2.0 PHY binding
2===========================================
3
4This binding describes the USB PHY hardware provided by the RCU module on the
5Lantiq XWAY SoCs.
6
7This node has to be a sub node of the Lantiq RCU block.
8
9-------------------------------------------------------------------------------
10Required properties (controller (parent) node):
11- compatible : Should be one of
12 "lantiq,ase-usb2-phy"
13 "lantiq,danube-usb2-phy"
14 "lantiq,xrx100-usb2-phy"
15 "lantiq,xrx200-usb2-phy"
16 "lantiq,xrx300-usb2-phy"
17- reg : Defines the following sets of registers in the parent
18 syscon device
19 - Offset of the USB PHY configuration register
20 - Offset of the USB Analog configuration
21 register (only for xrx200 and xrx200)
22- clocks : References to the (PMU) "phy" clk gate.
23- clock-names : Must be "phy"
24- resets : References to the RCU USB configuration reset bits.
25- reset-names : Must be one of the following:
26 "phy" (optional)
27 "ctrl" (shared)
28
29-------------------------------------------------------------------------------
30Example for the USB PHYs on an xRX200 SoC:
31 usb_phy0: usb2-phy@18 {
32 compatible = "lantiq,xrx200-usb2-phy";
33 reg = <0x18 4>, <0x38 4>;
34
35 clocks = <&pmu PMU_GATE_USB0_PHY>;
36 clock-names = "phy";
37 resets = <&reset1 4 4>, <&reset0 4 4>;
38 reset-names = "phy", "ctrl";
39 #phy-cells = <0>;
40 };
diff --git a/Documentation/devicetree/bindings/reset/lantiq,reset.txt b/Documentation/devicetree/bindings/reset/lantiq,reset.txt
new file mode 100644
index 000000000000..c6aef36b7d15
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/lantiq,reset.txt
@@ -0,0 +1,30 @@
1Lantiq XWAY SoC RCU reset controller binding
2============================================
3
4This binding describes a reset-controller found on the RCU module on Lantiq
5XWAY SoCs.
6
7This node has to be a sub node of the Lantiq RCU block.
8
9-------------------------------------------------------------------------------
10Required properties:
11- compatible : Should be one of
12 "lantiq,danube-reset"
13 "lantiq,xrx200-reset"
14- reg : Defines the following sets of registers in the parent
15 syscon device
16 - Offset of the reset set register
17 - Offset of the reset status register
18- #reset-cells : Specifies the number of cells needed to encode the
19 reset line, should be 2.
20 The first cell takes the reset set bit and the
21 second cell takes the status bit.
22
23-------------------------------------------------------------------------------
24Example for the reset-controllers on the xRX200 SoCs:
25 reset0: reset-controller@10 {
26 compatible = "lantiq,xrx200-reset";
27 reg <0x10 0x04>, <0x14 0x04>;
28
29 #reset-cells = <2>;
30 };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 69183f0fbc78..1ea1fd4232ab 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -361,6 +361,7 @@ variscite Variscite Ltd.
361via VIA Technologies, Inc. 361via VIA Technologies, Inc.
362virtio Virtual I/O Device Specification, developed by the OASIS consortium 362virtio Virtual I/O Device Specification, developed by the OASIS consortium
363vivante Vivante Corporation 363vivante Vivante Corporation
364vocore VoCore Studio
364voipac Voipac Technologies s.r.o. 365voipac Voipac Technologies s.r.o.
365wd Western Digital Corp. 366wd Western Digital Corp.
366wetek WeTek Electronics, limited. 367wetek WeTek Electronics, limited.
diff --git a/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt b/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt
new file mode 100644
index 000000000000..18d4d8302702
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt
@@ -0,0 +1,24 @@
1Lantiq WTD watchdog binding
2============================
3
4This describes the binding of the Lantiq watchdog driver.
5
6-------------------------------------------------------------------------------
7Required properties:
8- compatible : Should be one of
9 "lantiq,wdt"
10 "lantiq,xrx100-wdt"
11 "lantiq,xrx200-wdt", "lantiq,xrx100-wdt"
12 "lantiq,falcon-wdt"
13- reg : Address of the watchdog block
14- lantiq,rcu : A phandle to the RCU syscon (required for
15 "lantiq,falcon-wdt" and "lantiq,xrx100-wdt")
16
17-------------------------------------------------------------------------------
18Example for the watchdog on the xRX200 SoCs:
19 watchdog@803f0 {
20 compatible = "lantiq,xrx200-wdt", "lantiq,xrx100-wdt";
21 reg = <0x803f0 0x10>;
22
23 lantiq,rcu = <&rcu0>;
24 };
diff --git a/MAINTAINERS b/MAINTAINERS
index 4b914dd27bae..ef65785cdff2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7717,6 +7717,7 @@ M: John Crispin <john@phrozen.org>
7717L: linux-mips@linux-mips.org 7717L: linux-mips@linux-mips.org
7718S: Maintained 7718S: Maintained
7719F: arch/mips/lantiq 7719F: arch/mips/lantiq
7720F: drivers/soc/lantiq
7720 7721
7721LAPB module 7722LAPB module
7722L: linux-x25@vger.kernel.org 7723L: linux-x25@vger.kernel.org
@@ -8982,6 +8983,7 @@ M: Paul Burton <paul.burton@imgtec.com>
8982L: linux-mips@linux-mips.org 8983L: linux-mips@linux-mips.org
8983S: Supported 8984S: Supported
8984F: arch/mips/generic/ 8985F: arch/mips/generic/
8986F: arch/mips/tools/generic-board-config.sh
8985 8987
8986MIPS/LOONGSON1 ARCHITECTURE 8988MIPS/LOONGSON1 ARCHITECTURE
8987M: Keguang Zhang <keguang.zhang@gmail.com> 8989M: Keguang Zhang <keguang.zhang@gmail.com>
@@ -8992,6 +8994,13 @@ F: arch/mips/include/asm/mach-loongson32/
8992F: drivers/*/*loongson1* 8994F: drivers/*/*loongson1*
8993F: drivers/*/*/*loongson1* 8995F: drivers/*/*/*loongson1*
8994 8996
8997MIPS RINT INSTRUCTION EMULATION
8998M: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
8999L: linux-mips@linux-mips.org
9000S: Supported
9001F: arch/mips/math-emu/sp_rint.c
9002F: arch/mips/math-emu/dp_rint.c
9003
8995MIROSOUND PCM20 FM RADIO RECEIVER DRIVER 9004MIROSOUND PCM20 FM RADIO RECEIVER DRIVER
8996M: Hans Verkuil <hverkuil@xs4all.nl> 9005M: Hans Verkuil <hverkuil@xs4all.nl>
8997L: linux-media@vger.kernel.org 9006L: linux-media@vger.kernel.org
@@ -9869,6 +9878,12 @@ F: drivers/regulator/twl-regulator.c
9869F: drivers/regulator/twl6030-regulator.c 9878F: drivers/regulator/twl6030-regulator.c
9870F: include/linux/i2c-omap.h 9879F: include/linux/i2c-omap.h
9871 9880
9881ONION OMEGA2+ BOARD
9882M: Harvey Hunt <harveyhuntnexus@gmail.com>
9883L: linux-mips@linux-mips.org
9884S: Maintained
9885F: arch/mips/boot/dts/ralink/omega2p.dts
9886
9872OMFS FILESYSTEM 9887OMFS FILESYSTEM
9873M: Bob Copeland <me@bobcopeland.com> 9888M: Bob Copeland <me@bobcopeland.com>
9874L: linux-karma-devel@lists.sourceforge.net 9889L: linux-karma-devel@lists.sourceforge.net
@@ -14390,6 +14405,12 @@ L: netdev@vger.kernel.org
14390S: Maintained 14405S: Maintained
14391F: drivers/net/vmxnet3/ 14406F: drivers/net/vmxnet3/
14392 14407
14408VOCORE VOCORE2 BOARD
14409M: Harvey Hunt <harveyhuntnexus@gmail.com>
14410L: linux-mips@linux-mips.org
14411S: Maintained
14412F: arch/mips/boot/dts/ralink/vocore2.dts
14413
14393VOLTAGE AND CURRENT REGULATOR FRAMEWORK 14414VOLTAGE AND CURRENT REGULATOR FRAMEWORK
14394M: Liam Girdwood <lgirdwood@gmail.com> 14415M: Liam Girdwood <lgirdwood@gmail.com>
14395M: Mark Brown <broonie@kernel.org> 14416M: Mark Brown <broonie@kernel.org>
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 48d91d5be4e9..cb7fcc4216fd 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1627,14 +1627,6 @@ config CPU_R5500
1627 NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV 1627 NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
1628 instruction set. 1628 instruction set.
1629 1629
1630config CPU_R6000
1631 bool "R6000"
1632 depends on SYS_HAS_CPU_R6000
1633 select CPU_SUPPORTS_32BIT_KERNEL
1634 help
1635 MIPS Technologies R6000 and R6000A series processors. Note these
1636 processors are extremely rare and the support for them is incomplete.
1637
1638config CPU_NEVADA 1630config CPU_NEVADA
1639 bool "RM52xx" 1631 bool "RM52xx"
1640 depends on SYS_HAS_CPU_NEVADA 1632 depends on SYS_HAS_CPU_NEVADA
@@ -1950,9 +1942,6 @@ config SYS_HAS_CPU_R5432
1950config SYS_HAS_CPU_R5500 1942config SYS_HAS_CPU_R5500
1951 bool 1943 bool
1952 1944
1953config SYS_HAS_CPU_R6000
1954 bool
1955
1956config SYS_HAS_CPU_NEVADA 1945config SYS_HAS_CPU_NEVADA
1957 bool 1946 bool
1958 1947
@@ -2180,7 +2169,7 @@ config PAGE_SIZE_32KB
2180 2169
2181config PAGE_SIZE_64KB 2170config PAGE_SIZE_64KB
2182 bool "64kB" 2171 bool "64kB"
2183 depends on !CPU_R3000 && !CPU_TX39XX && !CPU_R6000 2172 depends on !CPU_R3000 && !CPU_TX39XX
2184 help 2173 help
2185 Using 64kB page size will result in higher performance kernel at 2174 Using 64kB page size will result in higher performance kernel at
2186 the price of higher memory consumption. This option is available on 2175 the price of higher memory consumption. This option is available on
@@ -2248,11 +2237,11 @@ config CPU_HAS_PREFETCH
2248 2237
2249config CPU_GENERIC_DUMP_TLB 2238config CPU_GENERIC_DUMP_TLB
2250 bool 2239 bool
2251 default y if !(CPU_R3000 || CPU_R6000 || CPU_R8000 || CPU_TX39XX) 2240 default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
2252 2241
2253config CPU_R4K_FPU 2242config CPU_R4K_FPU
2254 bool 2243 bool
2255 default y if !(CPU_R3000 || CPU_R6000 || CPU_TX39XX || CPU_CAVIUM_OCTEON) 2244 default y if !(CPU_R3000 || CPU_TX39XX)
2256 2245
2257config CPU_R4K_CACHE_TLB 2246config CPU_R4K_CACHE_TLB
2258 bool 2247 bool
@@ -2260,6 +2249,7 @@ config CPU_R4K_CACHE_TLB
2260 2249
2261config MIPS_MT_SMP 2250config MIPS_MT_SMP
2262 bool "MIPS MT SMP support (1 TC on each available VPE)" 2251 bool "MIPS MT SMP support (1 TC on each available VPE)"
2252 default y
2263 depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6 && !CPU_MICROMIPS 2253 depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6 && !CPU_MICROMIPS
2264 select CPU_MIPSR2_IRQ_VI 2254 select CPU_MIPSR2_IRQ_VI
2265 select CPU_MIPSR2_IRQ_EI 2255 select CPU_MIPSR2_IRQ_EI
@@ -2376,7 +2366,6 @@ config MIPS_CPS
2376 bool "MIPS Coherent Processing System support" 2366 bool "MIPS Coherent Processing System support"
2377 depends on SYS_SUPPORTS_MIPS_CPS 2367 depends on SYS_SUPPORTS_MIPS_CPS
2378 select MIPS_CM 2368 select MIPS_CM
2379 select MIPS_CPC
2380 select MIPS_CPS_PM if HOTPLUG_CPU 2369 select MIPS_CPS_PM if HOTPLUG_CPU
2381 select SMP 2370 select SMP
2382 select SYNC_R4K if (CEVT_R4K || CSRC_R4K) 2371 select SYNC_R4K if (CEVT_R4K || CSRC_R4K)
@@ -2393,11 +2382,11 @@ config MIPS_CPS
2393 2382
2394config MIPS_CPS_PM 2383config MIPS_CPS_PM
2395 depends on MIPS_CPS 2384 depends on MIPS_CPS
2396 select MIPS_CPC
2397 bool 2385 bool
2398 2386
2399config MIPS_CM 2387config MIPS_CM
2400 bool 2388 bool
2389 select MIPS_CPC
2401 2390
2402config MIPS_CPC 2391config MIPS_CPC
2403 bool 2392 bool
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index bc2708c9ada4..a96d97a806c9 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -151,7 +151,6 @@ cflags-y += -fno-stack-check
151# 151#
152cflags-$(CONFIG_CPU_R3000) += -march=r3000 152cflags-$(CONFIG_CPU_R3000) += -march=r3000
153cflags-$(CONFIG_CPU_TX39XX) += -march=r3900 153cflags-$(CONFIG_CPU_TX39XX) += -march=r3900
154cflags-$(CONFIG_CPU_R6000) += -march=r6000 -Wa,--trap
155cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap 154cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
156cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap 155cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
157cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap 156cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
@@ -291,7 +290,8 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
291 290
292bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ 291bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \
293 VMLINUX_ENTRY_ADDRESS=$(entry-y) \ 292 VMLINUX_ENTRY_ADDRESS=$(entry-y) \
294 PLATFORM="$(platform-y)" 293 PLATFORM="$(platform-y)" \
294 ITS_INPUTS="$(its-y)"
295ifdef CONFIG_32BIT 295ifdef CONFIG_32BIT
296bootvars-y += ADDR_BITS=32 296bootvars-y += ADDR_BITS=32
297endif 297endif
@@ -299,6 +299,10 @@ ifdef CONFIG_64BIT
299bootvars-y += ADDR_BITS=64 299bootvars-y += ADDR_BITS=64
300endif 300endif
301 301
302# This is required to get dwarf unwinding tables into .debug_frame
303# instead of .eh_frame so we don't discard them.
304KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
305
302LDFLAGS += -m $(ld-emul) 306LDFLAGS += -m $(ld-emul)
303 307
304ifdef CONFIG_MIPS 308ifdef CONFIG_MIPS
@@ -500,8 +504,14 @@ $(eval $(call gen_generic_defconfigs,micro32,r2,eb el))
500.PHONY: $(generic_defconfigs) 504.PHONY: $(generic_defconfigs)
501$(generic_defconfigs): 505$(generic_defconfigs):
502 $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \ 506 $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \
503 -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \ 507 -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ | \
504 $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config) 508 grep -Ev '^#'
509 $(Q)cp $(KCONFIG_CONFIG) $(objtree)/.config.$@
510 $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig \
511 KCONFIG_CONFIG=$(objtree)/.config.$@ >/dev/null
512 $(Q)$(CONFIG_SHELL) $(srctree)/arch/$(ARCH)/tools/generic-board-config.sh \
513 $(srctree) $(objtree) $(objtree)/.config.$@ $(KCONFIG_CONFIG) \
514 "$(origin BOARDS)" $(BOARDS)
505 $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig 515 $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
506 516
507# 517#
@@ -510,6 +520,19 @@ $(generic_defconfigs):
510$(generic_config_dir)/%.config: ; 520$(generic_config_dir)/%.config: ;
511 521
512# 522#
523# Prevent direct use of generic_defconfig, which is intended to be used as the
524# basis of the various ISA-specific targets generated above.
525#
526.PHONY: generic_defconfig
527generic_defconfig:
528 $(Q)echo "generic_defconfig is not intended for direct use, but should instead be"
529 $(Q)echo "used via an ISA-specific target from the following list:"
530 $(Q)echo
531 $(Q)for cfg in $(generic_defconfigs); do echo " $${cfg}"; done
532 $(Q)echo
533 $(Q)false
534
535#
513# Legacy defconfig compatibility - these targets used to be real defconfigs but 536# Legacy defconfig compatibility - these targets used to be real defconfigs but
514# now that the boards have been converted to use the generic kernel they are 537# now that the boards have been converted to use the generic kernel they are
515# wrappers around the generic rules above. 538# wrappers around the generic rules above.
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c
index 83831002c832..da7663770425 100644
--- a/arch/mips/alchemy/devboards/db1200.c
+++ b/arch/mips/alchemy/devboards/db1200.c
@@ -344,28 +344,32 @@ static struct platform_device db1200_ide_dev = {
344 344
345/* SD carddetects: they're supposed to be edge-triggered, but ack 345/* SD carddetects: they're supposed to be edge-triggered, but ack
346 * doesn't seem to work (CPLD Rev 2). Instead, the screaming one 346 * doesn't seem to work (CPLD Rev 2). Instead, the screaming one
347 * is disabled and its counterpart enabled. The 500ms timeout is 347 * is disabled and its counterpart enabled. The 200ms timeout is
348 * because the carddetect isn't debounced in hardware. 348 * because the carddetect usually triggers twice, after debounce.
349 */ 349 */
350static irqreturn_t db1200_mmc_cd(int irq, void *ptr) 350static irqreturn_t db1200_mmc_cd(int irq, void *ptr)
351{ 351{
352 void(*mmc_cd)(struct mmc_host *, unsigned long); 352 disable_irq_nosync(irq);
353 return IRQ_WAKE_THREAD;
354}
353 355
354 if (irq == DB1200_SD0_INSERT_INT) { 356static irqreturn_t db1200_mmc_cdfn(int irq, void *ptr)
355 disable_irq_nosync(DB1200_SD0_INSERT_INT); 357{
356 enable_irq(DB1200_SD0_EJECT_INT); 358 void (*mmc_cd)(struct mmc_host *, unsigned long);
357 } else {
358 disable_irq_nosync(DB1200_SD0_EJECT_INT);
359 enable_irq(DB1200_SD0_INSERT_INT);
360 }
361 359
362 /* link against CONFIG_MMC=m */ 360 /* link against CONFIG_MMC=m */
363 mmc_cd = symbol_get(mmc_detect_change); 361 mmc_cd = symbol_get(mmc_detect_change);
364 if (mmc_cd) { 362 if (mmc_cd) {
365 mmc_cd(ptr, msecs_to_jiffies(500)); 363 mmc_cd(ptr, msecs_to_jiffies(200));
366 symbol_put(mmc_detect_change); 364 symbol_put(mmc_detect_change);
367 } 365 }
368 366
367 msleep(100); /* debounce */
368 if (irq == DB1200_SD0_INSERT_INT)
369 enable_irq(DB1200_SD0_EJECT_INT);
370 else
371 enable_irq(DB1200_SD0_INSERT_INT);
372
369 return IRQ_HANDLED; 373 return IRQ_HANDLED;
370} 374}
371 375
@@ -374,13 +378,13 @@ static int db1200_mmc_cd_setup(void *mmc_host, int en)
374 int ret; 378 int ret;
375 379
376 if (en) { 380 if (en) {
377 ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd, 381 ret = request_threaded_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
378 0, "sd_insert", mmc_host); 382 db1200_mmc_cdfn, 0, "sd_insert", mmc_host);
379 if (ret) 383 if (ret)
380 goto out; 384 goto out;
381 385
382 ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd, 386 ret = request_threaded_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
383 0, "sd_eject", mmc_host); 387 db1200_mmc_cdfn, 0, "sd_eject", mmc_host);
384 if (ret) { 388 if (ret) {
385 free_irq(DB1200_SD0_INSERT_INT, mmc_host); 389 free_irq(DB1200_SD0_INSERT_INT, mmc_host);
386 goto out; 390 goto out;
@@ -436,23 +440,27 @@ static struct led_classdev db1200_mmc_led = {
436 440
437static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr) 441static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr)
438{ 442{
439 void(*mmc_cd)(struct mmc_host *, unsigned long); 443 disable_irq_nosync(irq);
444 return IRQ_WAKE_THREAD;
445}
440 446
441 if (irq == PB1200_SD1_INSERT_INT) { 447static irqreturn_t pb1200_mmc1_cdfn(int irq, void *ptr)
442 disable_irq_nosync(PB1200_SD1_INSERT_INT); 448{
443 enable_irq(PB1200_SD1_EJECT_INT); 449 void (*mmc_cd)(struct mmc_host *, unsigned long);
444 } else {
445 disable_irq_nosync(PB1200_SD1_EJECT_INT);
446 enable_irq(PB1200_SD1_INSERT_INT);
447 }
448 450
449 /* link against CONFIG_MMC=m */ 451 /* link against CONFIG_MMC=m */
450 mmc_cd = symbol_get(mmc_detect_change); 452 mmc_cd = symbol_get(mmc_detect_change);
451 if (mmc_cd) { 453 if (mmc_cd) {
452 mmc_cd(ptr, msecs_to_jiffies(500)); 454 mmc_cd(ptr, msecs_to_jiffies(200));
453 symbol_put(mmc_detect_change); 455 symbol_put(mmc_detect_change);
454 } 456 }
455 457
458 msleep(100); /* debounce */
459 if (irq == PB1200_SD1_INSERT_INT)
460 enable_irq(PB1200_SD1_EJECT_INT);
461 else
462 enable_irq(PB1200_SD1_INSERT_INT);
463
456 return IRQ_HANDLED; 464 return IRQ_HANDLED;
457} 465}
458 466
@@ -461,13 +469,13 @@ static int pb1200_mmc1_cd_setup(void *mmc_host, int en)
461 int ret; 469 int ret;
462 470
463 if (en) { 471 if (en) {
464 ret = request_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, 0, 472 ret = request_threaded_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd,
465 "sd1_insert", mmc_host); 473 pb1200_mmc1_cdfn, 0, "sd1_insert", mmc_host);
466 if (ret) 474 if (ret)
467 goto out; 475 goto out;
468 476
469 ret = request_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, 0, 477 ret = request_threaded_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd,
470 "sd1_eject", mmc_host); 478 pb1200_mmc1_cdfn, 0, "sd1_eject", mmc_host);
471 if (ret) { 479 if (ret) {
472 free_irq(PB1200_SD1_INSERT_INT, mmc_host); 480 free_irq(PB1200_SD1_INSERT_INT, mmc_host);
473 goto out; 481 goto out;
diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c
index 3e7fbdbdb3c4..cd1ae29f95a3 100644
--- a/arch/mips/alchemy/devboards/db1300.c
+++ b/arch/mips/alchemy/devboards/db1300.c
@@ -450,24 +450,27 @@ static struct platform_device db1300_ide_dev = {
450 450
451static irqreturn_t db1300_mmc_cd(int irq, void *ptr) 451static irqreturn_t db1300_mmc_cd(int irq, void *ptr)
452{ 452{
453 void(*mmc_cd)(struct mmc_host *, unsigned long); 453 disable_irq_nosync(irq);
454 return IRQ_WAKE_THREAD;
455}
454 456
455 /* disable the one currently screaming. No other way to shut it up */ 457static irqreturn_t db1300_mmc_cdfn(int irq, void *ptr)
456 if (irq == DB1300_SD1_INSERT_INT) { 458{
457 disable_irq_nosync(DB1300_SD1_INSERT_INT); 459 void (*mmc_cd)(struct mmc_host *, unsigned long);
458 enable_irq(DB1300_SD1_EJECT_INT);
459 } else {
460 disable_irq_nosync(DB1300_SD1_EJECT_INT);
461 enable_irq(DB1300_SD1_INSERT_INT);
462 }
463 460
464 /* link against CONFIG_MMC=m. We can only be called once MMC core has 461 /* link against CONFIG_MMC=m. We can only be called once MMC core has
465 * initialized the controller, so symbol_get() should always succeed. 462 * initialized the controller, so symbol_get() should always succeed.
466 */ 463 */
467 mmc_cd = symbol_get(mmc_detect_change); 464 mmc_cd = symbol_get(mmc_detect_change);
468 mmc_cd(ptr, msecs_to_jiffies(500)); 465 mmc_cd(ptr, msecs_to_jiffies(200));
469 symbol_put(mmc_detect_change); 466 symbol_put(mmc_detect_change);
470 467
468 msleep(100); /* debounce */
469 if (irq == DB1300_SD1_INSERT_INT)
470 enable_irq(DB1300_SD1_EJECT_INT);
471 else
472 enable_irq(DB1300_SD1_INSERT_INT);
473
471 return IRQ_HANDLED; 474 return IRQ_HANDLED;
472} 475}
473 476
@@ -487,13 +490,13 @@ static int db1300_mmc_cd_setup(void *mmc_host, int en)
487 int ret; 490 int ret;
488 491
489 if (en) { 492 if (en) {
490 ret = request_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd, 0, 493 ret = request_threaded_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd,
491 "sd_insert", mmc_host); 494 db1300_mmc_cdfn, 0, "sd_insert", mmc_host);
492 if (ret) 495 if (ret)
493 goto out; 496 goto out;
494 497
495 ret = request_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd, 0, 498 ret = request_threaded_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd,
496 "sd_eject", mmc_host); 499 db1300_mmc_cdfn, 0, "sd_eject", mmc_host);
497 if (ret) { 500 if (ret) {
498 free_irq(DB1300_SD1_INSERT_INT, mmc_host); 501 free_irq(DB1300_SD1_INSERT_INT, mmc_host);
499 goto out; 502 goto out;
diff --git a/arch/mips/alchemy/devboards/db1xxx.c b/arch/mips/alchemy/devboards/db1xxx.c
index 2d47f951121a..c9ad28995cd2 100644
--- a/arch/mips/alchemy/devboards/db1xxx.c
+++ b/arch/mips/alchemy/devboards/db1xxx.c
@@ -2,6 +2,7 @@
2 * Alchemy DB/PB1xxx board support. 2 * Alchemy DB/PB1xxx board support.
3 */ 3 */
4 4
5#include <asm/prom.h>
5#include <asm/mach-au1x00/au1000.h> 6#include <asm/mach-au1x00/au1000.h>
6#include <asm/mach-db1x00/bcsr.h> 7#include <asm/mach-db1x00/bcsr.h>
7 8
@@ -97,6 +98,7 @@ arch_initcall(db1xxx_arch_init);
97 98
98static int __init db1xxx_dev_init(void) 99static int __init db1xxx_dev_init(void)
99{ 100{
101 mips_set_machine_name(board_type_str());
100 switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { 102 switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
101 case BCSR_WHOAMI_DB1000: 103 case BCSR_WHOAMI_DB1000:
102 case BCSR_WHOAMI_DB1500: 104 case BCSR_WHOAMI_DB1500:
diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c
index dda422a0f36c..0137656107a9 100644
--- a/arch/mips/ar7/clock.c
+++ b/arch/mips/ar7/clock.c
@@ -430,6 +430,9 @@ EXPORT_SYMBOL(clk_disable);
430 430
431unsigned long clk_get_rate(struct clk *clk) 431unsigned long clk_get_rate(struct clk *clk)
432{ 432{
433 if (!clk)
434 return 0;
435
433 return clk->rate; 436 return clk->rate;
434} 437}
435EXPORT_SYMBOL(clk_get_rate); 438EXPORT_SYMBOL(clk_get_rate);
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index fa845953f736..6b1000b6a6a6 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -487,17 +487,16 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np)
487{ 487{
488 struct clk *ref_clk; 488 struct clk *ref_clk;
489 void __iomem *pll_base; 489 void __iomem *pll_base;
490 const char *dnfn = of_node_full_name(np);
491 490
492 ref_clk = of_clk_get(np, 0); 491 ref_clk = of_clk_get(np, 0);
493 if (IS_ERR(ref_clk)) { 492 if (IS_ERR(ref_clk)) {
494 pr_err("%s: of_clk_get failed\n", dnfn); 493 pr_err("%pOF: of_clk_get failed\n", np);
495 goto err; 494 goto err;
496 } 495 }
497 496
498 pll_base = of_iomap(np, 0); 497 pll_base = of_iomap(np, 0);
499 if (!pll_base) { 498 if (!pll_base) {
500 pr_err("%s: can't map pll registers\n", dnfn); 499 pr_err("%pOF: can't map pll registers\n", np);
501 goto err_clk; 500 goto err_clk;
502 } 501 }
503 502
@@ -506,12 +505,12 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np)
506 else if (of_device_is_compatible(np, "qca,ar9330-pll")) 505 else if (of_device_is_compatible(np, "qca,ar9330-pll"))
507 ar9330_clk_init(ref_clk, pll_base); 506 ar9330_clk_init(ref_clk, pll_base);
508 else { 507 else {
509 pr_err("%s: could not find any appropriate clk_init()\n", dnfn); 508 pr_err("%pOF: could not find any appropriate clk_init()\n", np);
510 goto err_iounmap; 509 goto err_iounmap;
511 } 510 }
512 511
513 if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { 512 if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
514 pr_err("%s: could not register clk provider\n", dnfn); 513 pr_err("%pOF: could not register clk provider\n", np);
515 goto err_iounmap; 514 goto err_iounmap;
516 } 515 }
517 516
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
index 73626040e4d6..19577f771c1f 100644
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -339,6 +339,9 @@ EXPORT_SYMBOL(clk_disable);
339 339
340unsigned long clk_get_rate(struct clk *clk) 340unsigned long clk_get_rate(struct clk *clk)
341{ 341{
342 if (!clk)
343 return 0;
344
342 return clk->rate; 345 return clk->rate;
343} 346}
344 347
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index 145b5ce8eb7e..1bd5c4f00d19 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -118,6 +118,12 @@ ifeq ($(ADDR_BITS),64)
118 itb_addr_cells = 2 118 itb_addr_cells = 2
119endif 119endif
120 120
121quiet_cmd_its_cat = CAT $@
122 cmd_its_cat = cat $^ >$@
123
124$(obj)/vmlinux.its.S: $(addprefix $(srctree)/arch/mips/$(PLATFORM)/,$(ITS_INPUTS))
125 $(call if_changed,its_cat)
126
121quiet_cmd_cpp_its_S = ITS $@ 127quiet_cmd_cpp_its_S = ITS $@
122 cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ 128 cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \
123 -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ 129 -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \
@@ -128,19 +134,19 @@ quiet_cmd_cpp_its_S = ITS $@
128 -DADDR_BITS=$(ADDR_BITS) \ 134 -DADDR_BITS=$(ADDR_BITS) \
129 -DADDR_CELLS=$(itb_addr_cells) 135 -DADDR_CELLS=$(itb_addr_cells)
130 136
131$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE 137$(obj)/vmlinux.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE
132 $(call if_changed_dep,cpp_its_S,none,vmlinux.bin) 138 $(call if_changed_dep,cpp_its_S,none,vmlinux.bin)
133 139
134$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE 140$(obj)/vmlinux.gz.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE
135 $(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz) 141 $(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz)
136 142
137$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE 143$(obj)/vmlinux.bz2.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE
138 $(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2) 144 $(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2)
139 145
140$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE 146$(obj)/vmlinux.lzma.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE
141 $(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma) 147 $(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma)
142 148
143$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE 149$(obj)/vmlinux.lzo.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE
144 $(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo) 150 $(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo)
145 151
146quiet_cmd_itb-image = ITB $@ 152quiet_cmd_itb-image = ITB $@
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index b9db49203e0c..cbac26ce063e 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -5,6 +5,7 @@ dts-dirs += ingenic
5dts-dirs += lantiq 5dts-dirs += lantiq
6dts-dirs += mti 6dts-dirs += mti
7dts-dirs += netlogic 7dts-dirs += netlogic
8dts-dirs += ni
8dts-dirs += pic32 9dts-dirs += pic32
9dts-dirs += qca 10dts-dirs += qca
10dts-dirs += ralink 11dts-dirs += ralink
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index fd138d9978c1..6c381844929c 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -1,6 +1,7 @@
1/dts-v1/; 1/dts-v1/;
2 2
3#include "jz4780.dtsi" 3#include "jz4780.dtsi"
4#include <dt-bindings/gpio/gpio.h>
4 5
5/ { 6/ {
6 compatible = "img,ci20", "ingenic,jz4780"; 7 compatible = "img,ci20", "ingenic,jz4780";
@@ -21,6 +22,13 @@
21 reg = <0x0 0x10000000 22 reg = <0x0 0x10000000
22 0x30000000 0x30000000>; 23 0x30000000 0x30000000>;
23 }; 24 };
25
26 eth0_power: fixedregulator@0 {
27 compatible = "regulator-fixed";
28 regulator-name = "eth0_power";
29 gpio = <&gpb 25 GPIO_ACTIVE_LOW>;
30 enable-active-high;
31 };
24}; 32};
25 33
26&ext { 34&ext {
@@ -123,6 +131,29 @@
123 }; 131 };
124 }; 132 };
125 }; 133 };
134
135 dm9000@6 {
136 compatible = "davicom,dm9000";
137 davicom,no-eeprom;
138
139 pinctrl-names = "default";
140 pinctrl-0 = <&pins_nemc_cs6>;
141
142 reg = <6 0 1 /* addr */
143 6 2 1>; /* data */
144
145 ingenic,nemc-tAS = <15>;
146 ingenic,nemc-tAH = <10>;
147 ingenic,nemc-tBP = <20>;
148 ingenic,nemc-tAW = <50>;
149 ingenic,nemc-tSTRV = <100>;
150
151 reset-gpios = <&gpf 12 GPIO_ACTIVE_HIGH>;
152 vcc-supply = <&eth0_power>;
153
154 interrupt-parent = <&gpe>;
155 interrupts = <19 4>;
156 };
126}; 157};
127 158
128&bch { 159&bch {
@@ -165,4 +196,10 @@
165 groups = "nemc-cs1"; 196 groups = "nemc-cs1";
166 bias-disable; 197 bias-disable;
167 }; 198 };
199
200 pins_nemc_cs6: nemc-cs6 {
201 function = "nemc-cs6";
202 groups = "nemc-cs6";
203 bias-disable;
204 };
168}; 205};
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi
index 4853ef67b3ab..e906134ecaef 100644
--- a/arch/mips/boot/dts/ingenic/jz4780.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi
@@ -44,6 +44,17 @@
44 #clock-cells = <1>; 44 #clock-cells = <1>;
45 }; 45 };
46 46
47 rtc_dev: rtc@10003000 {
48 compatible = "ingenic,jz4780-rtc";
49 reg = <0x10003000 0x4c>;
50
51 interrupt-parent = <&intc>;
52 interrupts = <32>;
53
54 clocks = <&cgu JZ4780_CLK_RTCLK>;
55 clock-names = "rtc";
56 };
57
47 pinctrl: pin-controller@10010000 { 58 pinctrl: pin-controller@10010000 {
48 compatible = "ingenic,jz4780-pinctrl"; 59 compatible = "ingenic,jz4780-pinctrl";
49 reg = <0x10010000 0x600>; 60 reg = <0x10010000 0x600>;
diff --git a/arch/mips/boot/dts/ni/169445.dts b/arch/mips/boot/dts/ni/169445.dts
new file mode 100644
index 000000000000..5389ef46c480
--- /dev/null
+++ b/arch/mips/boot/dts/ni/169445.dts
@@ -0,0 +1,100 @@
1/dts-v1/;
2
3/ {
4 #address-cells = <1>;
5 #size-cells = <1>;
6 compatible = "ni,169445";
7
8 cpus {
9 #address-cells = <1>;
10 #size-cells = <0>;
11 cpu@0 {
12 device_type = "cpu";
13 compatible = "mti,mips14KEc";
14 clocks = <&baseclk>;
15 reg = <0>;
16 };
17 };
18
19 memory@0 {
20 device_type = "memory";
21 reg = <0x0 0x10000000>;
22 };
23
24 baseclk: baseclock {
25 compatible = "fixed-clock";
26 #clock-cells = <0>;
27 clock-frequency = <50000000>;
28 };
29
30 cpu_intc: interrupt-controller {
31 #address-cells = <0>;
32 compatible = "mti,cpu-interrupt-controller";
33 interrupt-controller;
34 #interrupt-cells = <1>;
35 };
36
37 ahb@1f300000 {
38 compatible = "simple-bus";
39 #address-cells = <1>;
40 #size-cells = <1>;
41 ranges = <0x0 0x1f300000 0x80FFF>;
42
43 gpio1: gpio@10 {
44 compatible = "ni,169445-nand-gpio";
45 reg = <0x10 0x4>;
46 reg-names = "dat";
47 gpio-controller;
48 #gpio-cells = <2>;
49 };
50
51 gpio2: gpio@14 {
52 compatible = "ni,169445-nand-gpio";
53 reg = <0x14 0x4>;
54 reg-names = "dat";
55 gpio-controller;
56 #gpio-cells = <2>;
57 no-output;
58 };
59
60 nand@0 {
61 compatible = "gpio-control-nand";
62 nand-on-flash-bbt;
63 nand-ecc-mode = "soft_bch";
64 nand-ecc-step-size = <512>;
65 nand-ecc-strength = <4>;
66 reg = <0x0 4>;
67 gpios = <&gpio2 0 0>, /* rdy */
68 <&gpio1 1 0>, /* nce */
69 <&gpio1 2 0>, /* ale */
70 <&gpio1 3 0>, /* cle */
71 <&gpio1 4 0>; /* nwp */
72 };
73
74 serial@80000 {
75 compatible = "ns16550a";
76 reg = <0x80000 0x1000>;
77 interrupt-parent = <&cpu_intc>;
78 interrupts = <6>;
79 clocks = <&baseclk>;
80 reg-shift = <0>;
81 };
82
83 ethernet@40000 {
84 compatible = "snps,dwmac-4.10a";
85 interrupt-parent = <&cpu_intc>;
86 interrupts = <5>;
87 interrupt-names = "macirq";
88 reg = <0x40000 0x2000>;
89 clock-names = "stmmaceth", "pclk";
90 clocks = <&baseclk>, <&baseclk>;
91
92 phy-mode = "rgmii";
93
94 fixed-link {
95 speed = <1000>;
96 full-duplex;
97 };
98 };
99 };
100};
diff --git a/arch/mips/boot/dts/ni/Makefile b/arch/mips/boot/dts/ni/Makefile
new file mode 100644
index 000000000000..66cfdffc51c2
--- /dev/null
+++ b/arch/mips/boot/dts/ni/Makefile
@@ -0,0 +1,7 @@
1dtb-$(CONFIG_FIT_IMAGE_FDT_NI169445) += 169445.dtb
2
3# Force kbuild to make empty built-in.o if necessary
4obj- += dummy.o
5
6always := $(dtb-y)
7clean-files := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/ralink/Makefile b/arch/mips/boot/dts/ralink/Makefile
index 2a7225954bf6..55e2937b61f3 100644
--- a/arch/mips/boot/dts/ralink/Makefile
+++ b/arch/mips/boot/dts/ralink/Makefile
@@ -2,6 +2,8 @@ dtb-$(CONFIG_DTB_RT2880_EVAL) += rt2880_eval.dtb
2dtb-$(CONFIG_DTB_RT305X_EVAL) += rt3052_eval.dtb 2dtb-$(CONFIG_DTB_RT305X_EVAL) += rt3052_eval.dtb
3dtb-$(CONFIG_DTB_RT3883_EVAL) += rt3883_eval.dtb 3dtb-$(CONFIG_DTB_RT3883_EVAL) += rt3883_eval.dtb
4dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb 4dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb
5dtb-$(CONFIG_DTB_OMEGA2P) += omega2p.dtb
6dtb-$(CONFIG_DTB_VOCORE2) += vocore2.dtb
5 7
6obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) 8obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
7 9
diff --git a/arch/mips/boot/dts/ralink/mt7628a.dtsi b/arch/mips/boot/dts/ralink/mt7628a.dtsi
new file mode 100644
index 000000000000..9ff7e8faaecc
--- /dev/null
+++ b/arch/mips/boot/dts/ralink/mt7628a.dtsi
@@ -0,0 +1,126 @@
1/ {
2 #address-cells = <1>;
3 #size-cells = <1>;
4 compatible = "ralink,mt7628a-soc";
5
6 cpus {
7 #address-cells = <1>;
8 #size-cells = <0>;
9
10 cpu@0 {
11 compatible = "mti,mips24KEc";
12 device_type = "cpu";
13 reg = <0>;
14 };
15 };
16
17 resetc: reset-controller {
18 compatible = "ralink,rt2880-reset";
19 #reset-cells = <1>;
20 };
21
22 cpuintc: interrupt-controller {
23 #address-cells = <0>;
24 #interrupt-cells = <1>;
25 interrupt-controller;
26 compatible = "mti,cpu-interrupt-controller";
27 };
28
29 palmbus@10000000 {
30 compatible = "palmbus";
31 reg = <0x10000000 0x200000>;
32 ranges = <0x0 0x10000000 0x1FFFFF>;
33
34 #address-cells = <1>;
35 #size-cells = <1>;
36
37 sysc: system-controller@0 {
38 compatible = "ralink,mt7620a-sysc", "syscon";
39 reg = <0x0 0x100>;
40 };
41
42 intc: interrupt-controller@200 {
43 compatible = "ralink,rt2880-intc";
44 reg = <0x200 0x100>;
45
46 interrupt-controller;
47 #interrupt-cells = <1>;
48
49 resets = <&resetc 9>;
50 reset-names = "intc";
51
52 interrupt-parent = <&cpuintc>;
53 interrupts = <2>;
54
55 ralink,intc-registers = <0x9c 0xa0
56 0x6c 0xa4
57 0x80 0x78>;
58 };
59
60 memory-controller@300 {
61 compatible = "ralink,mt7620a-memc";
62 reg = <0x300 0x100>;
63 };
64
65 uart0: uartlite@c00 {
66 compatible = "ns16550a";
67 reg = <0xc00 0x100>;
68
69 resets = <&resetc 12>;
70 reset-names = "uart0";
71
72 interrupt-parent = <&intc>;
73 interrupts = <20>;
74
75 reg-shift = <2>;
76 };
77
78 uart1: uart1@d00 {
79 compatible = "ns16550a";
80 reg = <0xd00 0x100>;
81
82 resets = <&resetc 19>;
83 reset-names = "uart1";
84
85 interrupt-parent = <&intc>;
86 interrupts = <21>;
87
88 reg-shift = <2>;
89 };
90
91 uart2: uart2@e00 {
92 compatible = "ns16550a";
93 reg = <0xe00 0x100>;
94
95 resets = <&resetc 20>;
96 reset-names = "uart2";
97
98 interrupt-parent = <&intc>;
99 interrupts = <22>;
100
101 reg-shift = <2>;
102 };
103 };
104
105 usb_phy: usb-phy@10120000 {
106 compatible = "mediatek,mt7628-usbphy";
107 reg = <0x10120000 0x1000>;
108
109 #phy-cells = <0>;
110
111 ralink,sysctl = <&sysc>;
112 resets = <&resetc 22 &resetc 25>;
113 reset-names = "host", "device";
114 };
115
116 ehci@101c0000 {
117 compatible = "generic-ehci";
118 reg = <0x101c0000 0x1000>;
119
120 phys = <&usb_phy>;
121 phy-names = "usb";
122
123 interrupt-parent = <&intc>;
124 interrupts = <18>;
125 };
126};
diff --git a/arch/mips/boot/dts/ralink/omega2p.dts b/arch/mips/boot/dts/ralink/omega2p.dts
new file mode 100644
index 000000000000..5884fd48f59a
--- /dev/null
+++ b/arch/mips/boot/dts/ralink/omega2p.dts
@@ -0,0 +1,18 @@
1/dts-v1/;
2
3/include/ "mt7628a.dtsi"
4
5/ {
6 compatible = "onion,omega2+", "ralink,mt7688a-soc", "ralink,mt7628a-soc";
7 model = "Onion Omega2+";
8
9 memory@0 {
10 device_type = "memory";
11 reg = <0x0 0x8000000>;
12 };
13
14 chosen {
15 bootargs = "console=ttyS0,115200";
16 stdout-path = &uart0;
17 };
18};
diff --git a/arch/mips/boot/dts/ralink/vocore2.dts b/arch/mips/boot/dts/ralink/vocore2.dts
new file mode 100644
index 000000000000..fa8a5f8f236a
--- /dev/null
+++ b/arch/mips/boot/dts/ralink/vocore2.dts
@@ -0,0 +1,18 @@
1/dts-v1/;
2
3#include "mt7628a.dtsi"
4
5/ {
6 compatible = "vocore,vocore2", "ralink,mt7628a-soc";
7 model = "VoCore2";
8
9 memory@0 {
10 device_type = "memory";
11 reg = <0x0 0x8000000>;
12 };
13
14 chosen {
15 bootargs = "console=ttyS2,115200";
16 stdout-path = &uart2;
17 };
18};
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile
index b6d6e841a984..50b427879465 100644
--- a/arch/mips/cavium-octeon/executive/Makefile
+++ b/arch/mips/cavium-octeon/executive/Makefile
@@ -16,4 +16,4 @@ obj-y += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \
16 cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \ 16 cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \
17 cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o 17 cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o
18 18
19obj-y += cvmx-helper-errata.o cvmx-helper-jtag.o 19obj-y += cvmx-helper-errata.o cvmx-helper-jtag.o cvmx-boot-vector.o
diff --git a/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c b/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c
new file mode 100644
index 000000000000..b7019d21808e
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c
@@ -0,0 +1,167 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2004-2017 Cavium, Inc.
7 */
8
9
10/*
11 We install this program at the bootvector:
12------------------------------------
13 .set noreorder
14 .set nomacro
15 .set noat
16reset_vector:
17 dmtc0 $k0, $31, 0 # Save $k0 to DESAVE
18 dmtc0 $k1, $31, 3 # Save $k1 to KScratch2
19
20 mfc0 $k0, $12, 0 # Status
21 mfc0 $k1, $15, 1 # Ebase
22
23 ori $k0, 0x84 # Enable 64-bit addressing, set
24 # ERL (should already be set)
25 andi $k1, 0x3ff # mask out core ID
26
27 mtc0 $k0, $12, 0 # Status
28 sll $k1, 5
29
30 lui $k0, 0xbfc0
31 cache 17, 0($0) # Core-14345, clear L1 Dcache virtual
32 # tags if the core hit an NMI
33
34 ld $k0, 0x78($k0) # k0 <- (bfc00078) pointer to the reset vector
35 synci 0($0) # Invalidate ICache to get coherent
36 # view of target code.
37
38 daddu $k0, $k0, $k1
39 nop
40
41 ld $k0, 0($k0) # k0 <- core specific target address
42 dmfc0 $k1, $31, 3 # Restore $k1 from KScratch2
43
44 beqz $k0, wait_loop # Spin in wait loop
45 nop
46
47 jr $k0
48 nop
49
50 nop # NOPs needed here to fill delay slots
51 nop # on endian reversal of previous instructions
52
53wait_loop:
54 wait
55 nop
56
57 b wait_loop
58 nop
59
60 nop
61 nop
62------------------------------------
63
640000000000000000 <reset_vector>:
65 0: 40baf800 dmtc0 k0,c0_desave
66 4: 40bbf803 dmtc0 k1,c0_kscratch2
67
68 8: 401a6000 mfc0 k0,c0_status
69 c: 401b7801 mfc0 k1,c0_ebase
70
71 10: 375a0084 ori k0,k0,0x84
72 14: 337b03ff andi k1,k1,0x3ff
73
74 18: 409a6000 mtc0 k0,c0_status
75 1c: 001bd940 sll k1,k1,0x5
76
77 20: 3c1abfc0 lui k0,0xbfc0
78 24: bc110000 cache 0x11,0(zero)
79
80 28: df5a0078 ld k0,120(k0)
81 2c: 041f0000 synci 0(zero)
82
83 30: 035bd02d daddu k0,k0,k1
84 34: 00000000 nop
85
86 38: df5a0000 ld k0,0(k0)
87 3c: 403bf803 dmfc0 k1,c0_kscratch2
88
89 40: 13400005 beqz k0,58 <wait_loop>
90 44: 00000000 nop
91
92 48: 03400008 jr k0
93 4c: 00000000 nop
94
95 50: 00000000 nop
96 54: 00000000 nop
97
980000000000000058 <wait_loop>:
99 58: 42000020 wait
100 5c: 00000000 nop
101
102 60: 1000fffd b 58 <wait_loop>
103 64: 00000000 nop
104
105 68: 00000000 nop
106 6c: 00000000 nop
107
108 */
109
110#include <asm/octeon/cvmx-boot-vector.h>
111
112static unsigned long long _cvmx_bootvector_data[16] = {
113 0x40baf80040bbf803ull, /* patch low order 8-bits if no KScratch*/
114 0x401a6000401b7801ull,
115 0x375a0084337b03ffull,
116 0x409a6000001bd940ull,
117 0x3c1abfc0bc110000ull,
118 0xdf5a0078041f0000ull,
119 0x035bd02d00000000ull,
120 0xdf5a0000403bf803ull, /* patch low order 8-bits if no KScratch*/
121 0x1340000500000000ull,
122 0x0340000800000000ull,
123 0x0000000000000000ull,
124 0x4200002000000000ull,
125 0x1000fffd00000000ull,
126 0x0000000000000000ull,
127 OCTEON_BOOT_MOVEABLE_MAGIC1,
128 0 /* To be filled in with address of vector block*/
129};
130
131/* 2^10 CPUs */
132#define VECTOR_TABLE_SIZE (1024 * sizeof(struct cvmx_boot_vector_element))
133
134static void cvmx_boot_vector_init(void *mem)
135{
136 uint64_t kseg0_mem;
137 int i;
138
139 memset(mem, 0, VECTOR_TABLE_SIZE);
140 kseg0_mem = cvmx_ptr_to_phys(mem) | 0x8000000000000000ull;
141
142 for (i = 0; i < 15; i++) {
143 uint64_t v = _cvmx_bootvector_data[i];
144
145 if (OCTEON_IS_OCTEON1PLUS() && (i == 0 || i == 7))
146 v &= 0xffffffff00000000ull; /* KScratch not availble. */
147 cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8);
148 cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, v);
149 }
150 cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, 15 * 8);
151 cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, kseg0_mem);
152 cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000);
153}
154
155/**
156 * Get a pointer to the per-core table of reset vector pointers
157 *
158 */
159struct cvmx_boot_vector_element *cvmx_boot_vector_get(void)
160{
161 struct cvmx_boot_vector_element *ret;
162
163 ret = cvmx_bootmem_alloc_named_range_once(VECTOR_TABLE_SIZE, 0,
164 (1ull << 32) - 1, 8, "__boot_vector1__", cvmx_boot_vector_init);
165 return ret;
166}
167EXPORT_SYMBOL(cvmx_boot_vector_get);
diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
index 8d54d774933c..94d97ebfa036 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
@@ -44,6 +44,55 @@ static struct cvmx_bootmem_desc *cvmx_bootmem_desc;
44 44
45/* See header file for descriptions of functions */ 45/* See header file for descriptions of functions */
46 46
47/**
48 * This macro returns the size of a member of a structure.
49 * Logically it is the same as "sizeof(s::field)" in C++, but
50 * C lacks the "::" operator.
51 */
52#define SIZEOF_FIELD(s, field) sizeof(((s *)NULL)->field)
53
54/**
55 * This macro returns a member of the
56 * cvmx_bootmem_named_block_desc_t structure. These members can't
57 * be directly addressed as they might be in memory not directly
58 * reachable. In the case where bootmem is compiled with
59 * LINUX_HOST, the structure itself might be located on a remote
60 * Octeon. The argument "field" is the member name of the
61 * cvmx_bootmem_named_block_desc_t to read. Regardless of the type
62 * of the field, the return type is always a uint64_t. The "addr"
63 * parameter is the physical address of the structure.
64 */
65#define CVMX_BOOTMEM_NAMED_GET_FIELD(addr, field) \
66 __cvmx_bootmem_desc_get(addr, \
67 offsetof(struct cvmx_bootmem_named_block_desc, field), \
68 SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc, field))
69
70/**
71 * This function is the implementation of the get macros defined
72 * for individual structure members. The argument are generated
73 * by the macros inorder to read only the needed memory.
74 *
75 * @param base 64bit physical address of the complete structure
76 * @param offset Offset from the beginning of the structure to the member being
77 * accessed.
78 * @param size Size of the structure member.
79 *
80 * @return Value of the structure member promoted into a uint64_t.
81 */
82static inline uint64_t __cvmx_bootmem_desc_get(uint64_t base, int offset,
83 int size)
84{
85 base = (1ull << 63) | (base + offset);
86 switch (size) {
87 case 4:
88 return cvmx_read64_uint32(base);
89 case 8:
90 return cvmx_read64_uint64(base);
91 default:
92 return 0;
93 }
94}
95
47/* 96/*
48 * Wrapper functions are provided for reading/writing the size and 97 * Wrapper functions are provided for reading/writing the size and
49 * next block values as these may not be directly addressible (in 32 98 * next block values as these may not be directly addressible (in 32
@@ -98,6 +147,42 @@ void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment)
98 return cvmx_bootmem_alloc_range(size, alignment, 0, 0); 147 return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
99} 148}
100 149
150void *cvmx_bootmem_alloc_named_range_once(uint64_t size, uint64_t min_addr,
151 uint64_t max_addr, uint64_t align,
152 char *name,
153 void (*init) (void *))
154{
155 int64_t addr;
156 void *ptr;
157 uint64_t named_block_desc_addr;
158
159 named_block_desc_addr = (uint64_t)
160 cvmx_bootmem_phy_named_block_find(name,
161 (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING);
162
163 if (named_block_desc_addr) {
164 addr = CVMX_BOOTMEM_NAMED_GET_FIELD(named_block_desc_addr,
165 base_addr);
166 return cvmx_phys_to_ptr(addr);
167 }
168
169 addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr,
170 align, name,
171 (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING);
172
173 if (addr < 0)
174 return NULL;
175 ptr = cvmx_phys_to_ptr(addr);
176
177 if (init)
178 init(ptr);
179 else
180 memset(ptr, 0, size);
181
182 return ptr;
183}
184EXPORT_SYMBOL(cvmx_bootmem_alloc_named_range_once);
185
101void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, 186void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
102 uint64_t max_addr, uint64_t align, 187 uint64_t max_addr, uint64_t align,
103 char *name) 188 char *name)
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index c1eb1ff7c800..5b3a3f6a9ad3 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -2963,3 +2963,12 @@ void octeon_fixup_irqs(void)
2963} 2963}
2964 2964
2965#endif /* CONFIG_HOTPLUG_CPU */ 2965#endif /* CONFIG_HOTPLUG_CPU */
2966
2967struct irq_domain *octeon_irq_get_block_domain(int node, uint8_t block)
2968{
2969 struct octeon_ciu3_info *ciu3_info;
2970
2971 ciu3_info = octeon_ciu3_info_per_node[node & CVMX_NODE_MASK];
2972 return ciu3_info->domain[block];
2973}
2974EXPORT_SYMBOL(octeon_irq_get_block_domain);
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 3de786545ded..75e7c8625659 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -205,7 +205,7 @@ int plat_post_relocation(long offset)
205 * Firmware CPU startup hook 205 * Firmware CPU startup hook
206 * 206 *
207 */ 207 */
208static void octeon_boot_secondary(int cpu, struct task_struct *idle) 208static int octeon_boot_secondary(int cpu, struct task_struct *idle)
209{ 209{
210 int count; 210 int count;
211 211
@@ -223,8 +223,12 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle)
223 udelay(1); 223 udelay(1);
224 count--; 224 count--;
225 } 225 }
226 if (count == 0) 226 if (count == 0) {
227 pr_err("Secondary boot timeout\n"); 227 pr_err("Secondary boot timeout\n");
228 return -ETIMEDOUT;
229 }
230
231 return 0;
228} 232}
229 233
230/** 234/**
@@ -408,7 +412,7 @@ late_initcall(register_cavium_notifier);
408 412
409#endif /* CONFIG_HOTPLUG_CPU */ 413#endif /* CONFIG_HOTPLUG_CPU */
410 414
411struct plat_smp_ops octeon_smp_ops = { 415const struct plat_smp_ops octeon_smp_ops = {
412 .send_ipi_single = octeon_send_ipi_single, 416 .send_ipi_single = octeon_send_ipi_single,
413 .send_ipi_mask = octeon_send_ipi_mask, 417 .send_ipi_mask = octeon_send_ipi_mask,
414 .init_secondary = octeon_init_secondary, 418 .init_secondary = octeon_init_secondary,
@@ -485,7 +489,7 @@ static void octeon_78xx_send_ipi_mask(const struct cpumask *mask,
485 octeon_78xx_send_ipi_single(cpu, action); 489 octeon_78xx_send_ipi_single(cpu, action);
486} 490}
487 491
488static struct plat_smp_ops octeon_78xx_smp_ops = { 492static const struct plat_smp_ops octeon_78xx_smp_ops = {
489 .send_ipi_single = octeon_78xx_send_ipi_single, 493 .send_ipi_single = octeon_78xx_send_ipi_single,
490 .send_ipi_mask = octeon_78xx_send_ipi_mask, 494 .send_ipi_mask = octeon_78xx_send_ipi_mask,
491 .init_secondary = octeon_init_secondary, 495 .init_secondary = octeon_init_secondary,
@@ -501,7 +505,7 @@ static struct plat_smp_ops octeon_78xx_smp_ops = {
501 505
502void __init octeon_setup_smp(void) 506void __init octeon_setup_smp(void)
503{ 507{
504 struct plat_smp_ops *ops; 508 const struct plat_smp_ops *ops;
505 509
506 if (octeon_has_feature(OCTEON_FEATURE_CIU3)) 510 if (octeon_has_feature(OCTEON_FEATURE_CIU3))
507 ops = &octeon_78xx_smp_ops; 511 ops = &octeon_78xx_smp_ops;
diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig
index e5b18f1a31a0..490b12af103c 100644
--- a/arch/mips/configs/cavium_octeon_defconfig
+++ b/arch/mips/configs/cavium_octeon_defconfig
@@ -60,11 +60,8 @@ CONFIG_BLK_DEV_SD=y
60CONFIG_ATA=y 60CONFIG_ATA=y
61CONFIG_SATA_AHCI=y 61CONFIG_SATA_AHCI=y
62CONFIG_SATA_AHCI_PLATFORM=y 62CONFIG_SATA_AHCI_PLATFORM=y
63CONFIG_AHCI_OCTEON=y
64CONFIG_PATA_OCTEON_CF=y 63CONFIG_PATA_OCTEON_CF=y
65CONFIG_SATA_SIL=y
66CONFIG_NETDEVICES=y 64CONFIG_NETDEVICES=y
67CONFIG_MII=y
68# CONFIG_NET_VENDOR_3COM is not set 65# CONFIG_NET_VENDOR_3COM is not set
69# CONFIG_NET_VENDOR_ADAPTEC is not set 66# CONFIG_NET_VENDOR_ADAPTEC is not set
70# CONFIG_NET_VENDOR_ALTEON is not set 67# CONFIG_NET_VENDOR_ALTEON is not set
@@ -121,22 +118,30 @@ CONFIG_SPI=y
121CONFIG_SPI_OCTEON=y 118CONFIG_SPI_OCTEON=y
122# CONFIG_HWMON is not set 119# CONFIG_HWMON is not set
123CONFIG_WATCHDOG=y 120CONFIG_WATCHDOG=y
124CONFIG_USB=m 121CONFIG_USB=y
125CONFIG_USB_EHCI_HCD=m 122# CONFIG_USB_PCI is not set
126CONFIG_USB_EHCI_HCD_PLATFORM=m 123CONFIG_USB_XHCI_HCD=y
127CONFIG_USB_OHCI_HCD=m 124CONFIG_USB_EHCI_HCD=y
128CONFIG_USB_OHCI_HCD_PLATFORM=m 125CONFIG_USB_EHCI_HCD_PLATFORM=y
126CONFIG_USB_OHCI_HCD=y
127CONFIG_USB_OHCI_HCD_PLATFORM=y
128CONFIG_USB_STORAGE=y
129CONFIG_USB_DWC3=y
129CONFIG_MMC=y 130CONFIG_MMC=y
130# CONFIG_PWRSEQ_EMMC is not set 131# CONFIG_PWRSEQ_EMMC is not set
131# CONFIG_PWRSEQ_SIMPLE is not set 132# CONFIG_PWRSEQ_SIMPLE is not set
132# CONFIG_MMC_BLOCK_BOUNCE is not set
133CONFIG_MMC_CAVIUM_OCTEON=y 133CONFIG_MMC_CAVIUM_OCTEON=y
134CONFIG_EDAC=y
135CONFIG_EDAC_OCTEON_PC=y
136CONFIG_EDAC_OCTEON_L2C=y
137CONFIG_EDAC_OCTEON_LMC=y
138CONFIG_EDAC_OCTEON_PCI=y
134CONFIG_RTC_CLASS=y 139CONFIG_RTC_CLASS=y
135CONFIG_RTC_DRV_DS1307=y 140CONFIG_RTC_DRV_DS1307=y
136CONFIG_STAGING=y 141CONFIG_STAGING=y
137CONFIG_OCTEON_ETHERNET=y 142CONFIG_OCTEON_ETHERNET=y
138CONFIG_OCTEON_USB=m
139# CONFIG_IOMMU_SUPPORT is not set 143# CONFIG_IOMMU_SUPPORT is not set
144CONFIG_RAS=y
140CONFIG_EXT4_FS=y 145CONFIG_EXT4_FS=y
141CONFIG_EXT4_FS_POSIX_ACL=y 146CONFIG_EXT4_FS_POSIX_ACL=y
142CONFIG_EXT4_FS_SECURITY=y 147CONFIG_EXT4_FS_SECURITY=y
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
index b42cfa7865f9..5ea3104a3aca 100644
--- a/arch/mips/configs/ci20_defconfig
+++ b/arch/mips/configs/ci20_defconfig
@@ -91,6 +91,7 @@ CONFIG_SERIAL_OF_PLATFORM=y
91CONFIG_I2C=y 91CONFIG_I2C=y
92CONFIG_I2C_JZ4780=y 92CONFIG_I2C_JZ4780=y
93CONFIG_GPIO_SYSFS=y 93CONFIG_GPIO_SYSFS=y
94CONFIG_GPIO_INGENIC=y
94# CONFIG_HWMON is not set 95# CONFIG_HWMON is not set
95CONFIG_REGULATOR=y 96CONFIG_REGULATOR=y
96CONFIG_REGULATOR_DEBUG=y 97CONFIG_REGULATOR_DEBUG=y
@@ -99,6 +100,8 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
99# CONFIG_HID is not set 100# CONFIG_HID is not set
100# CONFIG_USB_SUPPORT is not set 101# CONFIG_USB_SUPPORT is not set
101CONFIG_MMC=y 102CONFIG_MMC=y
103CONFIG_RTC_CLASS=y
104CONFIG_RTC_DRV_JZ4740=y
102# CONFIG_IOMMU_SUPPORT is not set 105# CONFIG_IOMMU_SUPPORT is not set
103CONFIG_MEMORY=y 106CONFIG_MEMORY=y
104# CONFIG_DNOTIFY is not set 107# CONFIG_DNOTIFY is not set
diff --git a/arch/mips/configs/generic/board-ni169445.config b/arch/mips/configs/generic/board-ni169445.config
new file mode 100644
index 000000000000..f72223b366ca
--- /dev/null
+++ b/arch/mips/configs/generic/board-ni169445.config
@@ -0,0 +1,30 @@
1# require CONFIG_CPU_MIPS32_R2=y
2# require CONFIG_CPU_LITTLE_ENDIAN=y
3
4CONFIG_FIT_IMAGE_FDT_NI169445=y
5
6CONFIG_SERIAL_8250=y
7CONFIG_SERIAL_8250_CONSOLE=y
8CONFIG_SERIAL_OF_PLATFORM=y
9
10CONFIG_GPIOLIB=y
11CONFIG_GPIO_SYSFS=y
12CONFIG_GPIO_GENERIC_PLATFORM=y
13
14CONFIG_MTD=y
15CONFIG_MTD_BLOCK=y
16CONFIG_MTD_CMDLINE_PARTS=y
17
18CONFIG_MTD_NAND_ECC=y
19CONFIG_MTD_NAND_ECC_BCH=y
20CONFIG_MTD_NAND=y
21CONFIG_MTD_NAND_GPIO=y
22CONFIG_MTD_NAND_IDS=y
23
24CONFIG_MTD_UBI=y
25CONFIG_MTD_UBI_BLOCK=y
26
27CONFIG_NETDEVICES=y
28CONFIG_STMMAC_ETH=y
29CONFIG_STMMAC_PLATFORM=y
30CONFIG_DWMAC_GENERIC=y
diff --git a/arch/mips/configs/generic/board-sead-3.config b/arch/mips/configs/generic/board-sead-3.config
index 3b5e1ac579eb..df49a592dbb5 100644
--- a/arch/mips/configs/generic/board-sead-3.config
+++ b/arch/mips/configs/generic/board-sead-3.config
@@ -1,3 +1,5 @@
1# require CONFIG_32BIT=y
2
1CONFIG_LEGACY_BOARD_SEAD3=y 3CONFIG_LEGACY_BOARD_SEAD3=y
2 4
3CONFIG_AUXDISPLAY=y 5CONFIG_AUXDISPLAY=y
diff --git a/arch/mips/configs/generic_defconfig b/arch/mips/configs/generic_defconfig
index 91aacf2ef26d..26b1cd5ffbf5 100644
--- a/arch/mips/configs/generic_defconfig
+++ b/arch/mips/configs/generic_defconfig
@@ -3,7 +3,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
3CONFIG_MIPS_CPS=y 3CONFIG_MIPS_CPS=y
4CONFIG_CPU_HAS_MSA=y 4CONFIG_CPU_HAS_MSA=y
5CONFIG_HIGHMEM=y 5CONFIG_HIGHMEM=y
6CONFIG_NR_CPUS=2 6CONFIG_NR_CPUS=16
7CONFIG_MIPS_O32_FP64_SUPPORT=y 7CONFIG_MIPS_O32_FP64_SUPPORT=y
8CONFIG_SYSVIPC=y 8CONFIG_SYSVIPC=y
9CONFIG_NO_HZ_IDLE=y 9CONFIG_NO_HZ_IDLE=y
@@ -61,7 +61,6 @@ CONFIG_HID_KENSINGTON=y
61CONFIG_HID_LOGITECH=y 61CONFIG_HID_LOGITECH=y
62CONFIG_HID_MICROSOFT=y 62CONFIG_HID_MICROSOFT=y
63CONFIG_HID_MONTEREY=y 63CONFIG_HID_MONTEREY=y
64# CONFIG_USB_SUPPORT is not set
65# CONFIG_MIPS_PLATFORM_DEVICES is not set 64# CONFIG_MIPS_PLATFORM_DEVICES is not set
66# CONFIG_IOMMU_SUPPORT is not set 65# CONFIG_IOMMU_SUPPORT is not set
67CONFIG_EXT4_FS=y 66CONFIG_EXT4_FS=y
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig
index b1911816337c..55438fc9991e 100644
--- a/arch/mips/configs/gpr_defconfig
+++ b/arch/mips/configs/gpr_defconfig
@@ -111,12 +111,8 @@ CONFIG_ATALK=m
111CONFIG_DEV_APPLETALK=m 111CONFIG_DEV_APPLETALK=m
112CONFIG_IPDDP=m 112CONFIG_IPDDP=m
113CONFIG_IPDDP_ENCAP=y 113CONFIG_IPDDP_ENCAP=y
114CONFIG_IPDDP_DECAP=y
115CONFIG_X25=m 114CONFIG_X25=m
116CONFIG_LAPB=m 115CONFIG_LAPB=m
117CONFIG_ECONET=m
118CONFIG_ECONET_AUNUDP=y
119CONFIG_ECONET_NATIVE=y
120CONFIG_WAN_ROUTER=m 116CONFIG_WAN_ROUTER=m
121CONFIG_NET_SCHED=y 117CONFIG_NET_SCHED=y
122CONFIG_NET_SCH_CBQ=m 118CONFIG_NET_SCH_CBQ=m
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig
index 1ec8ed8d05d1..02be95c1b712 100644
--- a/arch/mips/configs/lemote2f_defconfig
+++ b/arch/mips/configs/lemote2f_defconfig
@@ -37,7 +37,6 @@ CONFIG_PM=y
37CONFIG_HIBERNATION=y 37CONFIG_HIBERNATION=y
38CONFIG_PM_STD_PARTITION="/dev/hda3" 38CONFIG_PM_STD_PARTITION="/dev/hda3"
39CONFIG_CPU_FREQ=y 39CONFIG_CPU_FREQ=y
40CONFIG_CPU_FREQ_DEBUG=y
41CONFIG_CPU_FREQ_STAT=y 40CONFIG_CPU_FREQ_STAT=y
42CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y 41CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
43CONFIG_CPU_FREQ_GOV_POWERSAVE=m 42CONFIG_CPU_FREQ_GOV_POWERSAVE=m
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 078ecac071ab..396408404487 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y
2CONFIG_CPU_LITTLE_ENDIAN=y 2CONFIG_CPU_LITTLE_ENDIAN=y
3CONFIG_CPU_MIPS32_R2=y 3CONFIG_CPU_MIPS32_R2=y
4CONFIG_PAGE_SIZE_16KB=y 4CONFIG_PAGE_SIZE_16KB=y
5CONFIG_MIPS_MT_SMP=y
6CONFIG_NR_CPUS=8 5CONFIG_NR_CPUS=8
7CONFIG_HZ_100=y 6CONFIG_HZ_100=y
8CONFIG_SYSVIPC=y 7CONFIG_SYSVIPC=y
diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig
index 80ecd94ed126..5691673a3327 100644
--- a/arch/mips/configs/malta_kvm_defconfig
+++ b/arch/mips/configs/malta_kvm_defconfig
@@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y
2CONFIG_CPU_LITTLE_ENDIAN=y 2CONFIG_CPU_LITTLE_ENDIAN=y
3CONFIG_CPU_MIPS32_R2=y 3CONFIG_CPU_MIPS32_R2=y
4CONFIG_PAGE_SIZE_16KB=y 4CONFIG_PAGE_SIZE_16KB=y
5CONFIG_MIPS_MT_SMP=y
6CONFIG_NR_CPUS=8 5CONFIG_NR_CPUS=8
7CONFIG_HZ_100=y 6CONFIG_HZ_100=y
8CONFIG_SYSVIPC=y 7CONFIG_SYSVIPC=y
diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig
index 35ad1f8d1a79..e9cadb37d684 100644
--- a/arch/mips/configs/malta_kvm_guest_defconfig
+++ b/arch/mips/configs/malta_kvm_guest_defconfig
@@ -3,6 +3,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
3CONFIG_CPU_MIPS32_R2=y 3CONFIG_CPU_MIPS32_R2=y
4CONFIG_KVM_GUEST=y 4CONFIG_KVM_GUEST=y
5CONFIG_PAGE_SIZE_16KB=y 5CONFIG_PAGE_SIZE_16KB=y
6# CONFIG_MIPS_MT_SMP is not set
6CONFIG_HZ_100=y 7CONFIG_HZ_100=y
7CONFIG_SYSVIPC=y 8CONFIG_SYSVIPC=y
8CONFIG_NO_HZ=y 9CONFIG_NO_HZ=y
diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig
index 55b68b981b05..d8c8f5fb8918 100644
--- a/arch/mips/configs/maltasmvp_defconfig
+++ b/arch/mips/configs/maltasmvp_defconfig
@@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y
2CONFIG_CPU_LITTLE_ENDIAN=y 2CONFIG_CPU_LITTLE_ENDIAN=y
3CONFIG_CPU_MIPS32_R2=y 3CONFIG_CPU_MIPS32_R2=y
4CONFIG_PAGE_SIZE_16KB=y 4CONFIG_PAGE_SIZE_16KB=y
5CONFIG_MIPS_MT_SMP=y
6CONFIG_SCHED_SMT=y 5CONFIG_SCHED_SMT=y
7CONFIG_MIPS_CPS=y 6CONFIG_MIPS_CPS=y
8CONFIG_NR_CPUS=8 7CONFIG_NR_CPUS=8
diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig
index 5ca590cf1635..04827bc9f87f 100644
--- a/arch/mips/configs/maltasmvp_eva_defconfig
+++ b/arch/mips/configs/maltasmvp_eva_defconfig
@@ -3,7 +3,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
3CONFIG_CPU_MIPS32_R2=y 3CONFIG_CPU_MIPS32_R2=y
4CONFIG_CPU_MIPS32_3_5_FEATURES=y 4CONFIG_CPU_MIPS32_3_5_FEATURES=y
5CONFIG_PAGE_SIZE_16KB=y 5CONFIG_PAGE_SIZE_16KB=y
6CONFIG_MIPS_MT_SMP=y
7CONFIG_SCHED_SMT=y 6CONFIG_SCHED_SMT=y
8CONFIG_MIPS_CPS=y 7CONFIG_MIPS_CPS=y
9CONFIG_NR_CPUS=8 8CONFIG_NR_CPUS=8
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 4011f1869e72..c3d0d0a6e044 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -146,12 +146,8 @@ CONFIG_ATALK=m
146CONFIG_DEV_APPLETALK=m 146CONFIG_DEV_APPLETALK=m
147CONFIG_IPDDP=m 147CONFIG_IPDDP=m
148CONFIG_IPDDP_ENCAP=y 148CONFIG_IPDDP_ENCAP=y
149CONFIG_IPDDP_DECAP=y
150CONFIG_X25=m 149CONFIG_X25=m
151CONFIG_LAPB=m 150CONFIG_LAPB=m
152CONFIG_ECONET=m
153CONFIG_ECONET_AUNUDP=y
154CONFIG_ECONET_NATIVE=y
155CONFIG_WAN_ROUTER=m 151CONFIG_WAN_ROUTER=m
156CONFIG_NET_SCHED=y 152CONFIG_NET_SCHED=y
157CONFIG_NET_SCH_CBQ=m 153CONFIG_NET_SCH_CBQ=m
diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig
index 5720ce23e9aa..7357248b3d7a 100644
--- a/arch/mips/configs/nlm_xlp_defconfig
+++ b/arch/mips/configs/nlm_xlp_defconfig
@@ -259,7 +259,6 @@ CONFIG_ATALK=m
259CONFIG_DEV_APPLETALK=m 259CONFIG_DEV_APPLETALK=m
260CONFIG_IPDDP=m 260CONFIG_IPDDP=m
261CONFIG_IPDDP_ENCAP=y 261CONFIG_IPDDP_ENCAP=y
262CONFIG_IPDDP_DECAP=y
263CONFIG_X25=m 262CONFIG_X25=m
264CONFIG_LAPB=m 263CONFIG_LAPB=m
265CONFIG_WAN_ROUTER=m 264CONFIG_WAN_ROUTER=m
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig
index fea56c535d92..1e18fd7de209 100644
--- a/arch/mips/configs/nlm_xlr_defconfig
+++ b/arch/mips/configs/nlm_xlr_defconfig
@@ -240,12 +240,8 @@ CONFIG_ATALK=m
240CONFIG_DEV_APPLETALK=m 240CONFIG_DEV_APPLETALK=m
241CONFIG_IPDDP=m 241CONFIG_IPDDP=m
242CONFIG_IPDDP_ENCAP=y 242CONFIG_IPDDP_ENCAP=y
243CONFIG_IPDDP_DECAP=y
244CONFIG_X25=m 243CONFIG_X25=m
245CONFIG_LAPB=m 244CONFIG_LAPB=m
246CONFIG_ECONET=m
247CONFIG_ECONET_AUNUDP=y
248CONFIG_ECONET_NATIVE=y
249CONFIG_WAN_ROUTER=m 245CONFIG_WAN_ROUTER=m
250CONFIG_PHONET=m 246CONFIG_PHONET=m
251CONFIG_IEEE802154=m 247CONFIG_IEEE802154=m
diff --git a/arch/mips/configs/omega2p_defconfig b/arch/mips/configs/omega2p_defconfig
new file mode 100644
index 000000000000..e2731c3cc7e7
--- /dev/null
+++ b/arch/mips/configs/omega2p_defconfig
@@ -0,0 +1,129 @@
1CONFIG_RALINK=y
2CONFIG_SOC_MT7620=y
3CONFIG_DTB_OMEGA2P=y
4CONFIG_CPU_MIPS32_R2=y
5# CONFIG_COMPACTION is not set
6CONFIG_HZ_100=y
7CONFIG_PREEMPT=y
8# CONFIG_SECCOMP is not set
9CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
10# CONFIG_LOCALVERSION_AUTO is not set
11CONFIG_SYSVIPC=y
12CONFIG_POSIX_MQUEUE=y
13CONFIG_NO_HZ_IDLE=y
14CONFIG_HIGH_RES_TIMERS=y
15CONFIG_IKCONFIG=y
16CONFIG_IKCONFIG_PROC=y
17CONFIG_LOG_BUF_SHIFT=14
18CONFIG_CGROUPS=y
19CONFIG_MEMCG=y
20CONFIG_CGROUP_SCHED=y
21CONFIG_CGROUP_FREEZER=y
22CONFIG_CGROUP_DEVICE=y
23CONFIG_CGROUP_CPUACCT=y
24CONFIG_NAMESPACES=y
25CONFIG_USER_NS=y
26CONFIG_CC_OPTIMIZE_FOR_SIZE=y
27CONFIG_SYSCTL_SYSCALL=y
28CONFIG_KALLSYMS_ALL=y
29CONFIG_EMBEDDED=y
30# CONFIG_VM_EVENT_COUNTERS is not set
31# CONFIG_SLUB_DEBUG is not set
32# CONFIG_COMPAT_BRK is not set
33# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
34# CONFIG_SUSPEND is not set
35CONFIG_NET=y
36CONFIG_PACKET=y
37CONFIG_UNIX=y
38CONFIG_INET=y
39# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
40# CONFIG_INET_XFRM_MODE_TUNNEL is not set
41# CONFIG_INET_XFRM_MODE_BEET is not set
42# CONFIG_INET_DIAG is not set
43# CONFIG_IPV6 is not set
44# CONFIG_WIRELESS is not set
45CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
46CONFIG_DEVTMPFS=y
47# CONFIG_FW_LOADER is not set
48# CONFIG_ALLOW_DEV_COREDUMP is not set
49CONFIG_NETDEVICES=y
50# CONFIG_ETHERNET is not set
51# CONFIG_WLAN is not set
52# CONFIG_INPUT_KEYBOARD is not set
53# CONFIG_INPUT_MOUSE is not set
54# CONFIG_SERIO is not set
55CONFIG_VT_HW_CONSOLE_BINDING=y
56CONFIG_LEGACY_PTY_COUNT=2
57CONFIG_SERIAL_8250=y
58CONFIG_SERIAL_8250_CONSOLE=y
59CONFIG_SERIAL_8250_NR_UARTS=3
60CONFIG_SERIAL_8250_RUNTIME_UARTS=3
61CONFIG_SERIAL_OF_PLATFORM=y
62# CONFIG_HW_RANDOM is not set
63# CONFIG_HWMON is not set
64# CONFIG_VGA_CONSOLE is not set
65CONFIG_USB=y
66CONFIG_USB_EHCI_HCD=y
67CONFIG_USB_EHCI_HCD_PLATFORM=y
68CONFIG_MMC=y
69# CONFIG_IOMMU_SUPPORT is not set
70CONFIG_MEMORY=y
71CONFIG_PHY_RALINK_USB=y
72# CONFIG_DNOTIFY is not set
73CONFIG_PROC_KCORE=y
74# CONFIG_PROC_PAGE_MONITOR is not set
75CONFIG_TMPFS=y
76CONFIG_CONFIGFS_FS=y
77# CONFIG_NETWORK_FILESYSTEMS is not set
78CONFIG_NLS_CODEPAGE_437=y
79CONFIG_NLS_CODEPAGE_737=y
80CONFIG_NLS_CODEPAGE_775=y
81CONFIG_NLS_CODEPAGE_850=y
82CONFIG_NLS_CODEPAGE_852=y
83CONFIG_NLS_CODEPAGE_855=y
84CONFIG_NLS_CODEPAGE_857=y
85CONFIG_NLS_CODEPAGE_860=y
86CONFIG_NLS_CODEPAGE_861=y
87CONFIG_NLS_CODEPAGE_862=y
88CONFIG_NLS_CODEPAGE_863=y
89CONFIG_NLS_CODEPAGE_864=y
90CONFIG_NLS_CODEPAGE_865=y
91CONFIG_NLS_CODEPAGE_866=y
92CONFIG_NLS_CODEPAGE_869=y
93CONFIG_NLS_CODEPAGE_936=y
94CONFIG_NLS_CODEPAGE_950=y
95CONFIG_NLS_CODEPAGE_932=y
96CONFIG_NLS_CODEPAGE_949=y
97CONFIG_NLS_CODEPAGE_874=y
98CONFIG_NLS_ISO8859_8=y
99CONFIG_NLS_CODEPAGE_1250=y
100CONFIG_NLS_CODEPAGE_1251=y
101CONFIG_NLS_ASCII=y
102CONFIG_NLS_ISO8859_1=y
103CONFIG_NLS_ISO8859_2=y
104CONFIG_NLS_ISO8859_3=y
105CONFIG_NLS_ISO8859_4=y
106CONFIG_NLS_ISO8859_5=y
107CONFIG_NLS_ISO8859_6=y
108CONFIG_NLS_ISO8859_7=y
109CONFIG_NLS_ISO8859_9=y
110CONFIG_NLS_ISO8859_13=y
111CONFIG_NLS_ISO8859_14=y
112CONFIG_NLS_ISO8859_15=y
113CONFIG_NLS_KOI8_R=y
114CONFIG_NLS_KOI8_U=y
115CONFIG_NLS_UTF8=y
116CONFIG_PRINTK_TIME=y
117CONFIG_DEBUG_INFO=y
118CONFIG_STRIP_ASM_SYMS=y
119CONFIG_DEBUG_FS=y
120CONFIG_MAGIC_SYSRQ=y
121CONFIG_PANIC_TIMEOUT=10
122# CONFIG_SCHED_DEBUG is not set
123# CONFIG_DEBUG_PREEMPT is not set
124CONFIG_STACKTRACE=y
125# CONFIG_FTRACE is not set
126CONFIG_CRYPTO_DEFLATE=y
127CONFIG_CRYPTO_LZO=y
128CONFIG_CRC16=y
129CONFIG_XZ_DEC=y
diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig
index 3598d58aac30..b22a3cf149b6 100644
--- a/arch/mips/configs/pistachio_defconfig
+++ b/arch/mips/configs/pistachio_defconfig
@@ -47,6 +47,8 @@ CONFIG_IP_ADVANCED_ROUTER=y
47CONFIG_IP_MULTIPLE_TABLES=y 47CONFIG_IP_MULTIPLE_TABLES=y
48CONFIG_IP_ROUTE_MULTIPATH=y 48CONFIG_IP_ROUTE_MULTIPATH=y
49CONFIG_IP_ROUTE_VERBOSE=y 49CONFIG_IP_ROUTE_VERBOSE=y
50CONFIG_IP_PNP=y
51CONFIG_IP_PNP_DHCP=y
50CONFIG_IP_MROUTE=y 52CONFIG_IP_MROUTE=y
51CONFIG_IP_PIMSM_V1=y 53CONFIG_IP_PIMSM_V1=y
52CONFIG_IP_PIMSM_V2=y 54CONFIG_IP_PIMSM_V2=y
@@ -292,7 +294,8 @@ CONFIG_SQUASHFS_LZO=y
292CONFIG_PSTORE=y 294CONFIG_PSTORE=y
293CONFIG_PSTORE_CONSOLE=y 295CONFIG_PSTORE_CONSOLE=y
294CONFIG_PSTORE_RAM=y 296CONFIG_PSTORE_RAM=y
295# CONFIG_NETWORK_FILESYSTEMS is not set 297CONFIG_NFS_FS=y
298CONFIG_ROOT_NFS=y
296CONFIG_NLS_DEFAULT="utf8" 299CONFIG_NLS_DEFAULT="utf8"
297CONFIG_NLS_CODEPAGE_437=m 300CONFIG_NLS_CODEPAGE_437=m
298CONFIG_NLS_ASCII=m 301CONFIG_NLS_ASCII=m
diff --git a/arch/mips/configs/vocore2_defconfig b/arch/mips/configs/vocore2_defconfig
new file mode 100644
index 000000000000..9121e4194a63
--- /dev/null
+++ b/arch/mips/configs/vocore2_defconfig
@@ -0,0 +1,129 @@
1CONFIG_RALINK=y
2CONFIG_SOC_MT7620=y
3CONFIG_DTB_VOCORE2=y
4CONFIG_CPU_MIPS32_R2=y
5# CONFIG_COMPACTION is not set
6CONFIG_HZ_100=y
7CONFIG_PREEMPT=y
8# CONFIG_SECCOMP is not set
9CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
10# CONFIG_LOCALVERSION_AUTO is not set
11CONFIG_SYSVIPC=y
12CONFIG_POSIX_MQUEUE=y
13CONFIG_NO_HZ_IDLE=y
14CONFIG_HIGH_RES_TIMERS=y
15CONFIG_IKCONFIG=y
16CONFIG_IKCONFIG_PROC=y
17CONFIG_LOG_BUF_SHIFT=14
18CONFIG_CGROUPS=y
19CONFIG_MEMCG=y
20CONFIG_CGROUP_SCHED=y
21CONFIG_CGROUP_FREEZER=y
22CONFIG_CGROUP_DEVICE=y
23CONFIG_CGROUP_CPUACCT=y
24CONFIG_NAMESPACES=y
25CONFIG_USER_NS=y
26CONFIG_CC_OPTIMIZE_FOR_SIZE=y
27CONFIG_SYSCTL_SYSCALL=y
28CONFIG_KALLSYMS_ALL=y
29CONFIG_EMBEDDED=y
30# CONFIG_VM_EVENT_COUNTERS is not set
31# CONFIG_SLUB_DEBUG is not set
32# CONFIG_COMPAT_BRK is not set
33# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
34# CONFIG_SUSPEND is not set
35CONFIG_NET=y
36CONFIG_PACKET=y
37CONFIG_UNIX=y
38CONFIG_INET=y
39# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
40# CONFIG_INET_XFRM_MODE_TUNNEL is not set
41# CONFIG_INET_XFRM_MODE_BEET is not set
42# CONFIG_INET_DIAG is not set
43# CONFIG_IPV6 is not set
44# CONFIG_WIRELESS is not set
45CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
46CONFIG_DEVTMPFS=y
47# CONFIG_FW_LOADER is not set
48# CONFIG_ALLOW_DEV_COREDUMP is not set
49CONFIG_NETDEVICES=y
50# CONFIG_ETHERNET is not set
51# CONFIG_WLAN is not set
52# CONFIG_INPUT_KEYBOARD is not set
53# CONFIG_INPUT_MOUSE is not set
54# CONFIG_SERIO is not set
55CONFIG_VT_HW_CONSOLE_BINDING=y
56CONFIG_LEGACY_PTY_COUNT=2
57CONFIG_SERIAL_8250=y
58CONFIG_SERIAL_8250_CONSOLE=y
59CONFIG_SERIAL_8250_NR_UARTS=3
60CONFIG_SERIAL_8250_RUNTIME_UARTS=3
61CONFIG_SERIAL_OF_PLATFORM=y
62# CONFIG_HW_RANDOM is not set
63# CONFIG_HWMON is not set
64# CONFIG_VGA_CONSOLE is not set
65CONFIG_USB=y
66CONFIG_USB_EHCI_HCD=y
67CONFIG_USB_EHCI_HCD_PLATFORM=y
68CONFIG_MMC=y
69# CONFIG_IOMMU_SUPPORT is not set
70CONFIG_MEMORY=y
71CONFIG_PHY_RALINK_USB=y
72# CONFIG_DNOTIFY is not set
73CONFIG_PROC_KCORE=y
74# CONFIG_PROC_PAGE_MONITOR is not set
75CONFIG_TMPFS=y
76CONFIG_CONFIGFS_FS=y
77# CONFIG_NETWORK_FILESYSTEMS is not set
78CONFIG_NLS_CODEPAGE_437=y
79CONFIG_NLS_CODEPAGE_737=y
80CONFIG_NLS_CODEPAGE_775=y
81CONFIG_NLS_CODEPAGE_850=y
82CONFIG_NLS_CODEPAGE_852=y
83CONFIG_NLS_CODEPAGE_855=y
84CONFIG_NLS_CODEPAGE_857=y
85CONFIG_NLS_CODEPAGE_860=y
86CONFIG_NLS_CODEPAGE_861=y
87CONFIG_NLS_CODEPAGE_862=y
88CONFIG_NLS_CODEPAGE_863=y
89CONFIG_NLS_CODEPAGE_864=y
90CONFIG_NLS_CODEPAGE_865=y
91CONFIG_NLS_CODEPAGE_866=y
92CONFIG_NLS_CODEPAGE_869=y
93CONFIG_NLS_CODEPAGE_936=y
94CONFIG_NLS_CODEPAGE_950=y
95CONFIG_NLS_CODEPAGE_932=y
96CONFIG_NLS_CODEPAGE_949=y
97CONFIG_NLS_CODEPAGE_874=y
98CONFIG_NLS_ISO8859_8=y
99CONFIG_NLS_CODEPAGE_1250=y
100CONFIG_NLS_CODEPAGE_1251=y
101CONFIG_NLS_ASCII=y
102CONFIG_NLS_ISO8859_1=y
103CONFIG_NLS_ISO8859_2=y
104CONFIG_NLS_ISO8859_3=y
105CONFIG_NLS_ISO8859_4=y
106CONFIG_NLS_ISO8859_5=y
107CONFIG_NLS_ISO8859_6=y
108CONFIG_NLS_ISO8859_7=y
109CONFIG_NLS_ISO8859_9=y
110CONFIG_NLS_ISO8859_13=y
111CONFIG_NLS_ISO8859_14=y
112CONFIG_NLS_ISO8859_15=y
113CONFIG_NLS_KOI8_R=y
114CONFIG_NLS_KOI8_U=y
115CONFIG_NLS_UTF8=y
116CONFIG_PRINTK_TIME=y
117CONFIG_DEBUG_INFO=y
118CONFIG_STRIP_ASM_SYMS=y
119CONFIG_DEBUG_FS=y
120CONFIG_MAGIC_SYSRQ=y
121CONFIG_PANIC_TIMEOUT=10
122# CONFIG_SCHED_DEBUG is not set
123# CONFIG_DEBUG_PREEMPT is not set
124CONFIG_STACKTRACE=y
125# CONFIG_FTRACE is not set
126CONFIG_CRYPTO_DEFLATE=y
127CONFIG_CRYPTO_LZO=y
128CONFIG_CRC16=y
129CONFIG_XZ_DEC=y
diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c
index 629b24db0d3a..008555969534 100644
--- a/arch/mips/fw/arc/init.c
+++ b/arch/mips/fw/arc/init.c
@@ -51,7 +51,7 @@ void __init prom_init(void)
51#endif 51#endif
52#ifdef CONFIG_SGI_IP27 52#ifdef CONFIG_SGI_IP27
53 { 53 {
54 extern struct plat_smp_ops ip27_smp_ops; 54 extern const struct plat_smp_ops ip27_smp_ops;
55 55
56 register_smp_ops(&ip27_smp_ops); 56 register_smp_ops(&ip27_smp_ops);
57 } 57 }
diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig
index 51ffbbaddee2..e0436aaf7f38 100644
--- a/arch/mips/generic/Kconfig
+++ b/arch/mips/generic/Kconfig
@@ -36,4 +36,10 @@ config FIT_IMAGE_FDT_BOSTON
36 enable this if you wish to boot on a MIPS Boston board, as it is 36 enable this if you wish to boot on a MIPS Boston board, as it is
37 expected by the bootloader. 37 expected by the bootloader.
38 38
39config FIT_IMAGE_FDT_NI169445
40 bool "Include FDT for NI 169445"
41 help
42 Enable this to include the FDT for the 169445 platform from
43 National Instruments in the FIT kernel image.
44
39endif 45endif
diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform
index 9a30d69e2281..f5312dfa8184 100644
--- a/arch/mips/generic/Platform
+++ b/arch/mips/generic/Platform
@@ -12,3 +12,7 @@ platform-$(CONFIG_MIPS_GENERIC) += generic/
12cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic 12cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic
13load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 13load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000
14all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb 14all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb
15
16its-y := vmlinux.its.S
17its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S
18its-$(CONFIG_FIT_IMAGE_FDT_NI169445) += board-ni169445.its.S
diff --git a/arch/mips/generic/board-boston.its.S b/arch/mips/generic/board-boston.its.S
new file mode 100644
index 000000000000..a7f51f97b910
--- /dev/null
+++ b/arch/mips/generic/board-boston.its.S
@@ -0,0 +1,22 @@
1/ {
2 images {
3 fdt@boston {
4 description = "img,boston Device Tree";
5 data = /incbin/("boot/dts/img/boston.dtb");
6 type = "flat_dt";
7 arch = "mips";
8 compression = "none";
9 hash@0 {
10 algo = "sha1";
11 };
12 };
13 };
14
15 configurations {
16 conf@boston {
17 description = "Boston Linux kernel";
18 kernel = "kernel@0";
19 fdt = "fdt@boston";
20 };
21 };
22};
diff --git a/arch/mips/generic/board-ni169445.its.S b/arch/mips/generic/board-ni169445.its.S
new file mode 100644
index 000000000000..d12e12fe90be
--- /dev/null
+++ b/arch/mips/generic/board-ni169445.its.S
@@ -0,0 +1,22 @@
1{
2 images {
3 fdt@ni169445 {
4 description = "NI 169445 device tree";
5 data = /incbin/("boot/dts/ni/169445.dtb");
6 type = "flat_dt";
7 arch = "mips";
8 compression = "none";
9 hash@0 {
10 algo = "sha1";
11 };
12 };
13 };
14
15 configurations {
16 conf@ni169445 {
17 description = "NI 169445 Linux Kernel";
18 kernel = "kernel@0";
19 fdt = "fdt@ni169445";
20 };
21 };
22};
diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c
index 3f32b376d30e..15a7fb8e2a2e 100644
--- a/arch/mips/generic/init.c
+++ b/arch/mips/generic/init.c
@@ -16,6 +16,7 @@
16#include <linux/of_fdt.h> 16#include <linux/of_fdt.h>
17#include <linux/of_platform.h> 17#include <linux/of_platform.h>
18 18
19#include <asm/bootinfo.h>
19#include <asm/fw/fw.h> 20#include <asm/fw/fw.h>
20#include <asm/irq_cpu.h> 21#include <asm/irq_cpu.h>
21#include <asm/machine.h> 22#include <asm/machine.h>
@@ -88,6 +89,8 @@ void __init *plat_get_fdt(void)
88 return (void *)fdt; 89 return (void *)fdt;
89} 90}
90 91
92#ifdef CONFIG_RELOCATABLE
93
91void __init plat_fdt_relocated(void *new_location) 94void __init plat_fdt_relocated(void *new_location)
92{ 95{
93 /* 96 /*
@@ -101,6 +104,8 @@ void __init plat_fdt_relocated(void *new_location)
101 fw_arg1 = (unsigned long)new_location; 104 fw_arg1 = (unsigned long)new_location;
102} 105}
103 106
107#endif /* CONFIG_RELOCATABLE */
108
104void __init plat_mem_setup(void) 109void __init plat_mem_setup(void)
105{ 110{
106 if (mach && mach->fixup_fdt) 111 if (mach && mach->fixup_fdt)
diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c
index 14064bdd91dd..5322d09dd51b 100644
--- a/arch/mips/generic/irq.c
+++ b/arch/mips/generic/irq.c
@@ -12,10 +12,11 @@
12#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
13#include <linux/clocksource.h> 13#include <linux/clocksource.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/irqchip/mips-gic.h>
16#include <linux/types.h> 15#include <linux/types.h>
17 16
18#include <asm/irq.h> 17#include <asm/irq.h>
18#include <asm/mips-cps.h>
19#include <asm/time.h>
19 20
20int get_c0_fdc_int(void) 21int get_c0_fdc_int(void)
21{ 22{
@@ -23,7 +24,7 @@ int get_c0_fdc_int(void)
23 24
24 if (cpu_has_veic) 25 if (cpu_has_veic)
25 panic("Unimplemented!"); 26 panic("Unimplemented!");
26 else if (gic_present) 27 else if (mips_gic_present())
27 mips_cpu_fdc_irq = gic_get_c0_fdc_int(); 28 mips_cpu_fdc_irq = gic_get_c0_fdc_int();
28 else if (cp0_fdc_irq >= 0) 29 else if (cp0_fdc_irq >= 0)
29 mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq; 30 mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
@@ -39,7 +40,7 @@ int get_c0_perfcount_int(void)
39 40
40 if (cpu_has_veic) 41 if (cpu_has_veic)
41 panic("Unimplemented!"); 42 panic("Unimplemented!");
42 else if (gic_present) 43 else if (mips_gic_present())
43 mips_cpu_perf_irq = gic_get_c0_perfcount_int(); 44 mips_cpu_perf_irq = gic_get_c0_perfcount_int();
44 else if (cp0_perfcount_irq >= 0) 45 else if (cp0_perfcount_irq >= 0)
45 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 46 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
@@ -55,7 +56,7 @@ unsigned int get_c0_compare_int(void)
55 56
56 if (cpu_has_veic) 57 if (cpu_has_veic)
57 panic("Unimplemented!"); 58 panic("Unimplemented!");
58 else if (gic_present) 59 else if (mips_gic_present())
59 mips_cpu_timer_irq = gic_get_c0_compare_int(); 60 mips_cpu_timer_irq = gic_get_c0_compare_int();
60 else 61 else
61 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 62 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
diff --git a/arch/mips/generic/vmlinux.its.S b/arch/mips/generic/vmlinux.its.S
index 3390e2f80b80..f67fbf1c8541 100644
--- a/arch/mips/generic/vmlinux.its.S
+++ b/arch/mips/generic/vmlinux.its.S
@@ -29,28 +29,3 @@
29 }; 29 };
30 }; 30 };
31}; 31};
32
33#ifdef CONFIG_FIT_IMAGE_FDT_BOSTON
34/ {
35 images {
36 fdt@boston {
37 description = "img,boston Device Tree";
38 data = /incbin/("boot/dts/img/boston.dtb");
39 type = "flat_dt";
40 arch = "mips";
41 compression = "none";
42 hash@0 {
43 algo = "sha1";
44 };
45 };
46 };
47
48 configurations {
49 conf@boston {
50 description = "Boston Linux kernel";
51 kernel = "kernel@0";
52 fdt = "fdt@boston";
53 };
54 };
55};
56#endif /* CONFIG_FIT_IMAGE_FDT_BOSTON */
diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h
index 859cf7048347..81fae23ce7cd 100644
--- a/arch/mips/include/asm/asm.h
+++ b/arch/mips/include/asm/asm.h
@@ -55,6 +55,7 @@
55 .type symbol, @function; \ 55 .type symbol, @function; \
56 .ent symbol, 0; \ 56 .ent symbol, 0; \
57symbol: .frame sp, 0, ra; \ 57symbol: .frame sp, 0, ra; \
58 .cfi_startproc; \
58 .insn 59 .insn
59 60
60/* 61/*
@@ -66,12 +67,14 @@ symbol: .frame sp, 0, ra; \
66 .type symbol, @function; \ 67 .type symbol, @function; \
67 .ent symbol, 0; \ 68 .ent symbol, 0; \
68symbol: .frame sp, framesize, rpc; \ 69symbol: .frame sp, framesize, rpc; \
70 .cfi_startproc; \
69 .insn 71 .insn
70 72
71/* 73/*
72 * END - mark end of function 74 * END - mark end of function
73 */ 75 */
74#define END(function) \ 76#define END(function) \
77 .cfi_endproc; \
75 .end function; \ 78 .end function; \
76 .size function, .-function 79 .size function, .-function
77 80
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h
index a92aee7b977a..b3e2975f83d3 100644
--- a/arch/mips/include/asm/bmips.h
+++ b/arch/mips/include/asm/bmips.h
@@ -48,8 +48,8 @@
48#include <asm/r4kcache.h> 48#include <asm/r4kcache.h>
49#include <asm/smp-ops.h> 49#include <asm/smp-ops.h>
50 50
51extern struct plat_smp_ops bmips43xx_smp_ops; 51extern const struct plat_smp_ops bmips43xx_smp_ops;
52extern struct plat_smp_ops bmips5000_smp_ops; 52extern const struct plat_smp_ops bmips5000_smp_ops;
53 53
54static inline int register_bmips_smp_ops(void) 54static inline int register_bmips_smp_ops(void)
55{ 55{
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index cd6efb07c980..a41059d47d31 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -15,6 +15,8 @@
15#include <linux/cache.h> 15#include <linux/cache.h>
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18#include <asm/mipsregs.h>
19
18/* 20/*
19 * Descriptor for a cache 21 * Descriptor for a cache
20 */ 22 */
@@ -77,17 +79,10 @@ struct cpuinfo_mips {
77 struct cache_desc tcache; /* Tertiary/split secondary cache */ 79 struct cache_desc tcache; /* Tertiary/split secondary cache */
78 int srsets; /* Shadow register sets */ 80 int srsets; /* Shadow register sets */
79 int package;/* physical package number */ 81 int package;/* physical package number */
80 int core; /* physical core number */ 82 unsigned int globalnumber;
81#ifdef CONFIG_64BIT 83#ifdef CONFIG_64BIT
82 int vmbits; /* Virtual memory size in bits */ 84 int vmbits; /* Virtual memory size in bits */
83#endif 85#endif
84#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
85 /*
86 * There is not necessarily a 1:1 mapping of VPE num to CPU number
87 * in particular on multi-core systems.
88 */
89 int vpe_id; /* Virtual Processor number */
90#endif
91 void *data; /* Additional data */ 86 void *data; /* Additional data */
92 unsigned int watch_reg_count; /* Number that exist */ 87 unsigned int watch_reg_count; /* Number that exist */
93 unsigned int watch_reg_use_cnt; /* Usable by ptrace */ 88 unsigned int watch_reg_use_cnt; /* Usable by ptrace */
@@ -144,11 +139,52 @@ struct proc_cpuinfo_notifier_args {
144 unsigned long n; 139 unsigned long n;
145}; 140};
146 141
147#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) 142static inline unsigned int cpu_cluster(struct cpuinfo_mips *cpuinfo)
148# define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) 143{
149#else 144 /* Optimisation for systems where multiple clusters aren't used */
150# define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; }) 145 if (!IS_ENABLED(CONFIG_CPU_MIPSR6))
151#endif 146 return 0;
147
148 return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CLUSTER) >>
149 MIPS_GLOBALNUMBER_CLUSTER_SHF;
150}
151
152static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
153{
154 return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >>
155 MIPS_GLOBALNUMBER_CORE_SHF;
156}
157
158static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
159{
160 /* Optimisation for systems where VP(E)s aren't used */
161 if (!IS_ENABLED(CONFIG_MIPS_MT_SMP) && !IS_ENABLED(CONFIG_CPU_MIPSR6))
162 return 0;
163
164 return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_VP) >>
165 MIPS_GLOBALNUMBER_VP_SHF;
166}
167
168extern void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster);
169extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
170extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
171
172static inline bool cpus_are_siblings(int cpua, int cpub)
173{
174 struct cpuinfo_mips *infoa = &cpu_data[cpua];
175 struct cpuinfo_mips *infob = &cpu_data[cpub];
176 unsigned int gnuma, gnumb;
177
178 if (infoa->package != infob->package)
179 return false;
180
181 gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
182 gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
183 if (gnuma != gnumb)
184 return false;
185
186 return true;
187}
152 188
153static inline unsigned long cpu_asid_inc(void) 189static inline unsigned long cpu_asid_inc(void)
154{ 190{
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h
index 175fe565f4e1..a45af3de075d 100644
--- a/arch/mips/include/asm/cpu-type.h
+++ b/arch/mips/include/asm/cpu-type.h
@@ -151,11 +151,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
151 case CPU_R5500: 151 case CPU_R5500:
152#endif 152#endif
153 153
154#ifdef CONFIG_SYS_HAS_CPU_R6000
155 case CPU_R6000:
156 case CPU_R6000A:
157#endif
158
159#ifdef CONFIG_SYS_HAS_CPU_NEVADA 154#ifdef CONFIG_SYS_HAS_CPU_NEVADA
160 case CPU_NEVADA: 155 case CPU_NEVADA:
161#endif 156#endif
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index d0c152b989f8..ece9b84f3bcb 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -286,11 +286,6 @@ enum cpu_type_enum {
286 CPU_R3081, CPU_R3081E, 286 CPU_R3081, CPU_R3081E,
287 287
288 /* 288 /*
289 * R6000 class processors
290 */
291 CPU_R6000, CPU_R6000A,
292
293 /*
294 * R4000 class processors 289 * R4000 class processors
295 */ 290 */
296 CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310, 291 CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310,
diff --git a/arch/mips/include/asm/floppy.h b/arch/mips/include/asm/floppy.h
index d75aed36480a..021d09ae5670 100644
--- a/arch/mips/include/asm/floppy.h
+++ b/arch/mips/include/asm/floppy.h
@@ -10,11 +10,11 @@
10#ifndef _ASM_FLOPPY_H 10#ifndef _ASM_FLOPPY_H
11#define _ASM_FLOPPY_H 11#define _ASM_FLOPPY_H
12 12
13#include <linux/dma-mapping.h> 13#include <asm/io.h>
14 14
15static inline void fd_cacheflush(char * addr, long size) 15static inline void fd_cacheflush(char * addr, long size)
16{ 16{
17 dma_cache_sync(NULL, addr, size, DMA_BIDIRECTIONAL); 17 dma_cache_wback_inv((unsigned long)addr, size);
18} 18}
19 19
20#define MAX_BUFFER_SECTORS 24 20#define MAX_BUFFER_SECTORS 24
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index c05369e0b8d6..b36097d3cbf4 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -36,6 +36,7 @@ struct mips_fpu_emulator_stats {
36 unsigned long emulated; 36 unsigned long emulated;
37 unsigned long loads; 37 unsigned long loads;
38 unsigned long stores; 38 unsigned long stores;
39 unsigned long branches;
39 unsigned long cp1ops; 40 unsigned long cp1ops;
40 unsigned long cp1xops; 41 unsigned long cp1xops;
41 unsigned long errors; 42 unsigned long errors;
@@ -45,6 +46,121 @@ struct mips_fpu_emulator_stats {
45 unsigned long ieee754_zerodiv; 46 unsigned long ieee754_zerodiv;
46 unsigned long ieee754_invalidop; 47 unsigned long ieee754_invalidop;
47 unsigned long ds_emul; 48 unsigned long ds_emul;
49
50 unsigned long abs_s;
51 unsigned long abs_d;
52 unsigned long add_s;
53 unsigned long add_d;
54 unsigned long bc1eqz;
55 unsigned long bc1nez;
56 unsigned long ceil_w_s;
57 unsigned long ceil_w_d;
58 unsigned long ceil_l_s;
59 unsigned long ceil_l_d;
60 unsigned long class_s;
61 unsigned long class_d;
62 unsigned long cmp_af_s;
63 unsigned long cmp_af_d;
64 unsigned long cmp_eq_s;
65 unsigned long cmp_eq_d;
66 unsigned long cmp_le_s;
67 unsigned long cmp_le_d;
68 unsigned long cmp_lt_s;
69 unsigned long cmp_lt_d;
70 unsigned long cmp_ne_s;
71 unsigned long cmp_ne_d;
72 unsigned long cmp_or_s;
73 unsigned long cmp_or_d;
74 unsigned long cmp_ueq_s;
75 unsigned long cmp_ueq_d;
76 unsigned long cmp_ule_s;
77 unsigned long cmp_ule_d;
78 unsigned long cmp_ult_s;
79 unsigned long cmp_ult_d;
80 unsigned long cmp_un_s;
81 unsigned long cmp_un_d;
82 unsigned long cmp_une_s;
83 unsigned long cmp_une_d;
84 unsigned long cmp_saf_s;
85 unsigned long cmp_saf_d;
86 unsigned long cmp_seq_s;
87 unsigned long cmp_seq_d;
88 unsigned long cmp_sle_s;
89 unsigned long cmp_sle_d;
90 unsigned long cmp_slt_s;
91 unsigned long cmp_slt_d;
92 unsigned long cmp_sne_s;
93 unsigned long cmp_sne_d;
94 unsigned long cmp_sor_s;
95 unsigned long cmp_sor_d;
96 unsigned long cmp_sueq_s;
97 unsigned long cmp_sueq_d;
98 unsigned long cmp_sule_s;
99 unsigned long cmp_sule_d;
100 unsigned long cmp_sult_s;
101 unsigned long cmp_sult_d;
102 unsigned long cmp_sun_s;
103 unsigned long cmp_sun_d;
104 unsigned long cmp_sune_s;
105 unsigned long cmp_sune_d;
106 unsigned long cvt_d_l;
107 unsigned long cvt_d_s;
108 unsigned long cvt_d_w;
109 unsigned long cvt_l_s;
110 unsigned long cvt_l_d;
111 unsigned long cvt_s_d;
112 unsigned long cvt_s_l;
113 unsigned long cvt_s_w;
114 unsigned long cvt_w_s;
115 unsigned long cvt_w_d;
116 unsigned long div_s;
117 unsigned long div_d;
118 unsigned long floor_w_s;
119 unsigned long floor_w_d;
120 unsigned long floor_l_s;
121 unsigned long floor_l_d;
122 unsigned long maddf_s;
123 unsigned long maddf_d;
124 unsigned long max_s;
125 unsigned long max_d;
126 unsigned long maxa_s;
127 unsigned long maxa_d;
128 unsigned long min_s;
129 unsigned long min_d;
130 unsigned long mina_s;
131 unsigned long mina_d;
132 unsigned long mov_s;
133 unsigned long mov_d;
134 unsigned long msubf_s;
135 unsigned long msubf_d;
136 unsigned long mul_s;
137 unsigned long mul_d;
138 unsigned long neg_s;
139 unsigned long neg_d;
140 unsigned long recip_s;
141 unsigned long recip_d;
142 unsigned long rint_s;
143 unsigned long rint_d;
144 unsigned long round_w_s;
145 unsigned long round_w_d;
146 unsigned long round_l_s;
147 unsigned long round_l_d;
148 unsigned long rsqrt_s;
149 unsigned long rsqrt_d;
150 unsigned long sel_s;
151 unsigned long sel_d;
152 unsigned long seleqz_s;
153 unsigned long seleqz_d;
154 unsigned long selnez_s;
155 unsigned long selnez_d;
156 unsigned long sqrt_s;
157 unsigned long sqrt_d;
158 unsigned long sub_s;
159 unsigned long sub_d;
160 unsigned long trunc_w_s;
161 unsigned long trunc_w_d;
162 unsigned long trunc_l_s;
163 unsigned long trunc_l_d;
48}; 164};
49 165
50DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); 166DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
@@ -62,7 +178,7 @@ do { \
62 178
63extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, 179extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
64 struct mips_fpu_struct *ctx, int has_fpu, 180 struct mips_fpu_struct *ctx, int has_fpu,
65 void *__user *fault_addr); 181 void __user **fault_addr);
66void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, 182void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
67 struct task_struct *tsk); 183 struct task_struct *tsk);
68int process_fpemu_return(int sig, void __user *fault_addr, 184int process_fpemu_return(int sig, void __user *fault_addr,
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index ecabc00c1e66..0cbf3af37eca 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -632,4 +632,6 @@ extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
632 */ 632 */
633#define xlate_dev_kmem_ptr(p) p 633#define xlate_dev_kmem_ptr(p) p
634 634
635void __ioread64_copy(void *to, const void __iomem *from, size_t count);
636
635#endif /* _ASM_IO_H */ 637#endif /* _ASM_IO_H */
diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
index bace5b9ae4df..f439cf9cf9d1 100644
--- a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
@@ -8,12 +8,16 @@
8#define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H 8#define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H
9 9
10#define cpu_has_tlb 1 10#define cpu_has_tlb 1
11#define cpu_has_ftlb 0
11#define cpu_has_tlbinv 0 12#define cpu_has_tlbinv 0
12#define cpu_has_segments 0 13#define cpu_has_segments 0
13#define cpu_has_eva 0 14#define cpu_has_eva 0
14#define cpu_has_htw 0 15#define cpu_has_htw 0
16#define cpu_has_ldpte 0
15#define cpu_has_rixiex 0 17#define cpu_has_rixiex 0
16#define cpu_has_maar 0 18#define cpu_has_maar 0
19#define cpu_has_rw_llb 0
20#define cpu_has_3kex 0
17#define cpu_has_4kex 1 21#define cpu_has_4kex 1
18#define cpu_has_3k_cache 0 22#define cpu_has_3k_cache 0
19#define cpu_has_4k_cache 1 23#define cpu_has_4k_cache 1
@@ -30,6 +34,12 @@
30#define cpu_has_mcheck 1 34#define cpu_has_mcheck 1
31#define cpu_has_ejtag 1 35#define cpu_has_ejtag 1
32#define cpu_has_llsc 1 36#define cpu_has_llsc 1
37#define cpu_has_guestctl0ext 0
38#define cpu_has_guestctl1 0
39#define cpu_has_guestctl2 0
40#define cpu_has_guestid 0
41#define cpu_has_drg 0
42#define cpu_has_bp_ghist 0
33#define cpu_has_mips16 0 43#define cpu_has_mips16 0
34#define cpu_has_mips16e2 0 44#define cpu_has_mips16e2 0
35#define cpu_has_mdmx 0 45#define cpu_has_mdmx 0
@@ -37,17 +47,23 @@
37#define cpu_has_smartmips 0 47#define cpu_has_smartmips 0
38#define cpu_has_rixi 0 48#define cpu_has_rixi 0
39#define cpu_has_mmips 0 49#define cpu_has_mmips 0
50#define cpu_has_lpa 0
51#define cpu_has_mhv 0
40#define cpu_has_vtag_icache 0 52#define cpu_has_vtag_icache 0
41#define cpu_has_dc_aliases 0 53#define cpu_has_dc_aliases 0
42#define cpu_has_ic_fills_f_dc 1 54#define cpu_has_ic_fills_f_dc 1
43#define cpu_has_pindexed_dcache 0 55#define cpu_has_pindexed_dcache 0
44#define cpu_has_mips32r1 1 56#define cpu_has_mips32r1 1
45#define cpu_has_mips32r2 0 57#define cpu_has_mips32r2 0
58#define cpu_has_mips32r6 0
46#define cpu_has_mips64r1 0 59#define cpu_has_mips64r1 0
47#define cpu_has_mips64r2 0 60#define cpu_has_mips64r2 0
61#define cpu_has_mips64r6 0
48#define cpu_has_dsp 0 62#define cpu_has_dsp 0
49#define cpu_has_dsp2 0 63#define cpu_has_dsp2 0
64#define cpu_has_dsp3 0
50#define cpu_has_mipsmt 0 65#define cpu_has_mipsmt 0
66#define cpu_has_vp 0
51#define cpu_has_userlocal 0 67#define cpu_has_userlocal 0
52#define cpu_has_nofpuex 0 68#define cpu_has_nofpuex 0
53#define cpu_has_64bits 0 69#define cpu_has_64bits 0
@@ -58,9 +74,19 @@
58 74
59#define cpu_dcache_line_size() 32 75#define cpu_dcache_line_size() 32
60#define cpu_icache_line_size() 32 76#define cpu_icache_line_size() 32
77#define cpu_scache_line_size() 0
61 78
62#define cpu_has_perf_cntr_intr_bit 0 79#define cpu_has_perf_cntr_intr_bit 0
63#define cpu_has_vz 0 80#define cpu_has_vz 0
64#define cpu_has_msa 0 81#define cpu_has_msa 0
82#define cpu_has_fre 0
83#define cpu_has_cdmm 0
84#define cpu_has_small_pages 0
85#define cpu_has_nan_legacy 1
86#define cpu_has_nan_2008 1
87#define cpu_has_ebase_wg 0
88#define cpu_has_badinstr 0
89#define cpu_has_badinstrp 0
90#define cpu_has_contextconfig 0
65 91
66#endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */ 92#endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
index 5035f09c5427..24080af570f9 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -710,7 +710,7 @@
710/* Broadcom 6345 ENET DMA definitions */ 710/* Broadcom 6345 ENET DMA definitions */
711#define ENETDMA_6345_CHANCFG_REG (0x00) 711#define ENETDMA_6345_CHANCFG_REG (0x00)
712 712
713#define ENETDMA_6345_MAXBURST_REG (0x40) 713#define ENETDMA_6345_MAXBURST_REG (0x04)
714 714
715#define ENETDMA_6345_RSTART_REG (0x08) 715#define ENETDMA_6345_RSTART_REG (0x08)
716 716
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index bd8b9bbe1771..a4f798629c3d 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -46,9 +46,9 @@
46#define cpu_has_64bits 1 46#define cpu_has_64bits 1
47#define cpu_has_octeon_cache 1 47#define cpu_has_octeon_cache 1
48#define cpu_has_saa octeon_has_saa() 48#define cpu_has_saa octeon_has_saa()
49#define cpu_has_mips32r1 0 49#define cpu_has_mips32r1 1
50#define cpu_has_mips32r2 0 50#define cpu_has_mips32r2 1
51#define cpu_has_mips64r1 0 51#define cpu_has_mips64r1 1
52#define cpu_has_mips64r2 1 52#define cpu_has_mips64r2 1
53#define cpu_has_dsp 0 53#define cpu_has_dsp 0
54#define cpu_has_dsp2 0 54#define cpu_has_dsp2 0
diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h
index defd135e7ac8..3fb7a0e09494 100644
--- a/arch/mips/include/asm/mach-ip27/topology.h
+++ b/arch/mips/include/asm/mach-ip27/topology.h
@@ -23,7 +23,6 @@ struct cpuinfo_ip27 {
23extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS]; 23extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
24 24
25#define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid) 25#define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid)
26#define parent_node(node) (node)
27#define cpumask_of_node(node) ((node) == -1 ? \ 26#define cpumask_of_node(node) ((node) == -1 ? \
28 cpu_all_mask : \ 27 cpu_all_mask : \
29 &hub_data(node)->h_cpus) 28 &hub_data(node)->h_cpus)
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
index 8064d7a4b33d..d750f93232e4 100644
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -46,8 +46,6 @@ extern struct clk *clk_get_ppe(void);
46 46
47/* find out what bootsource we have */ 47/* find out what bootsource we have */
48extern unsigned char ltq_boot_select(void); 48extern unsigned char ltq_boot_select(void);
49/* find out what caused the last cpu reset */
50extern int ltq_reset_cause(void);
51/* find out the soc type */ 49/* find out the soc type */
52extern int ltq_soc_type(void); 50extern int ltq_soc_type(void);
53 51
diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
index c68c0cc879c6..d0ae5d55413b 100644
--- a/arch/mips/include/asm/mach-loongson64/loongson.h
+++ b/arch/mips/include/asm/mach-loongson64/loongson.h
@@ -26,7 +26,7 @@ extern void mach_prepare_shutdown(void);
26/* environment arguments from bootloader */ 26/* environment arguments from bootloader */
27extern u32 cpu_clock_freq; 27extern u32 cpu_clock_freq;
28extern u32 memsize, highmemsize; 28extern u32 memsize, highmemsize;
29extern struct plat_smp_ops loongson3_smp_ops; 29extern const struct plat_smp_ops loongson3_smp_ops;
30 30
31/* loongson-specific command line, env and memory initialization */ 31/* loongson-specific command line, env and memory initialization */
32extern void __init prom_init_memory(void); 32extern void __init prom_init_memory(void);
diff --git a/arch/mips/include/asm/mach-loongson64/topology.h b/arch/mips/include/asm/mach-loongson64/topology.h
index 0d8f3b55bdbc..bcb885615fca 100644
--- a/arch/mips/include/asm/mach-loongson64/topology.h
+++ b/arch/mips/include/asm/mach-loongson64/topology.h
@@ -4,7 +4,6 @@
4#ifdef CONFIG_NUMA 4#ifdef CONFIG_NUMA
5 5
6#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) 6#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2)
7#define parent_node(node) (node)
8#define cpumask_of_node(node) (&__node_data[(node)]->cpumask) 7#define cpumask_of_node(node) (&__node_data[(node)]->cpumask)
9 8
10struct pci_bus; 9struct pci_bus;
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index 987ff580466b..817698abf2eb 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -10,8 +10,6 @@
10#ifndef _MIPS_MALTAINT_H 10#ifndef _MIPS_MALTAINT_H
11#define _MIPS_MALTAINT_H 11#define _MIPS_MALTAINT_H
12 12
13#include <linux/irqchip/mips-gic.h>
14
15/* 13/*
16 * Interrupts 0..15 are used for Malta ISA compatible interrupts 14 * Interrupts 0..15 are used for Malta ISA compatible interrupts
17 */ 15 */
@@ -62,7 +60,4 @@
62#define MSC01E_INT_PERFCTR 10 60#define MSC01E_INT_PERFCTR 10
63#define MSC01E_INT_CPUCTR 11 61#define MSC01E_INT_CPUCTR 11
64 62
65/* GIC external interrupts */
66#define GIC_INT_I8259A GIC_SHARED_TO_HWIRQ(3)
67
68#endif /* !(_MIPS_MALTAINT_H) */ 63#endif /* !(_MIPS_MALTAINT_H) */
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index cfdbab015769..f6231b91b724 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -8,16 +8,18 @@
8 * option) any later version. 8 * option) any later version.
9 */ 9 */
10 10
11#ifndef __MIPS_ASM_MIPS_CPS_H__
12# error Please include asm/mips-cps.h rather than asm/mips-cm.h
13#endif
14
11#ifndef __MIPS_ASM_MIPS_CM_H__ 15#ifndef __MIPS_ASM_MIPS_CM_H__
12#define __MIPS_ASM_MIPS_CM_H__ 16#define __MIPS_ASM_MIPS_CM_H__
13 17
14#include <linux/bitops.h> 18#include <linux/bitops.h>
15#include <linux/errno.h> 19#include <linux/errno.h>
16#include <linux/io.h>
17#include <linux/types.h>
18 20
19/* The base address of the CM GCR block */ 21/* The base address of the CM GCR block */
20extern void __iomem *mips_cm_base; 22extern void __iomem *mips_gcr_base;
21 23
22/* The base address of the CM L2-only sync region */ 24/* The base address of the CM L2-only sync region */
23extern void __iomem *mips_cm_l2sync_base; 25extern void __iomem *mips_cm_l2sync_base;
@@ -80,7 +82,7 @@ static inline int mips_cm_probe(void)
80static inline bool mips_cm_present(void) 82static inline bool mips_cm_present(void)
81{ 83{
82#ifdef CONFIG_MIPS_CM 84#ifdef CONFIG_MIPS_CM
83 return mips_cm_base != NULL; 85 return mips_gcr_base != NULL;
84#else 86#else
85 return false; 87 return false;
86#endif 88#endif
@@ -112,321 +114,219 @@ static inline bool mips_cm_has_l2sync(void)
112/* Size of the L2-only sync region */ 114/* Size of the L2-only sync region */
113#define MIPS_CM_L2SYNC_SIZE 0x1000 115#define MIPS_CM_L2SYNC_SIZE 0x1000
114 116
115/* Macros to ease the creation of register access functions */ 117#define GCR_ACCESSOR_RO(sz, off, name) \
116#define BUILD_CM_R_(name, off) \ 118 CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name) \
117static inline unsigned long __iomem *addr_gcr_##name(void) \ 119 CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name)
118{ \ 120
119 return (unsigned long __iomem *)(mips_cm_base + (off)); \ 121#define GCR_ACCESSOR_RW(sz, off, name) \
120} \ 122 CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name) \
121 \ 123 CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name)
122static inline u32 read32_gcr_##name(void) \ 124
123{ \ 125#define GCR_CX_ACCESSOR_RO(sz, off, name) \
124 return __raw_readl(addr_gcr_##name()); \ 126 CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \
125} \ 127 CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
126 \ 128
127static inline u64 read64_gcr_##name(void) \ 129#define GCR_CX_ACCESSOR_RW(sz, off, name) \
128{ \ 130 CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \
129 void __iomem *addr = addr_gcr_##name(); \ 131 CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
130 u64 ret; \ 132
131 \ 133/* GCR_CONFIG - Information about the system */
132 if (mips_cm_is64) { \ 134GCR_ACCESSOR_RO(64, 0x000, config)
133 ret = __raw_readq(addr); \ 135#define CM_GCR_CONFIG_CLUSTER_COH_CAPABLE BIT_ULL(43)
134 } else { \ 136#define CM_GCR_CONFIG_CLUSTER_ID GENMASK_ULL(39, 32)
135 ret = __raw_readl(addr); \ 137#define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23)
136 ret |= (u64)__raw_readl(addr + 0x4) << 32; \ 138#define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8)
137 } \ 139#define CM_GCR_CONFIG_PCORES GENMASK(7, 0)
138 \ 140
139 return ret; \ 141/* GCR_BASE - Base address of the Global Configuration Registers (GCRs) */
140} \ 142GCR_ACCESSOR_RW(64, 0x008, base)
141 \ 143#define CM_GCR_BASE_GCRBASE GENMASK_ULL(47, 15)
142static inline unsigned long read_gcr_##name(void) \ 144#define CM_GCR_BASE_CMDEFTGT GENMASK(1, 0)
143{ \
144 if (mips_cm_is64) \
145 return read64_gcr_##name(); \
146 else \
147 return read32_gcr_##name(); \
148}
149
150#define BUILD_CM__W(name, off) \
151static inline void write32_gcr_##name(u32 value) \
152{ \
153 __raw_writel(value, addr_gcr_##name()); \
154} \
155 \
156static inline void write64_gcr_##name(u64 value) \
157{ \
158 __raw_writeq(value, addr_gcr_##name()); \
159} \
160 \
161static inline void write_gcr_##name(unsigned long value) \
162{ \
163 if (mips_cm_is64) \
164 write64_gcr_##name(value); \
165 else \
166 write32_gcr_##name(value); \
167}
168
169#define BUILD_CM_RW(name, off) \
170 BUILD_CM_R_(name, off) \
171 BUILD_CM__W(name, off)
172
173#define BUILD_CM_Cx_R_(name, off) \
174 BUILD_CM_R_(cl_##name, MIPS_CM_CLCB_OFS + (off)) \
175 BUILD_CM_R_(co_##name, MIPS_CM_COCB_OFS + (off))
176
177#define BUILD_CM_Cx__W(name, off) \
178 BUILD_CM__W(cl_##name, MIPS_CM_CLCB_OFS + (off)) \
179 BUILD_CM__W(co_##name, MIPS_CM_COCB_OFS + (off))
180
181#define BUILD_CM_Cx_RW(name, off) \
182 BUILD_CM_Cx_R_(name, off) \
183 BUILD_CM_Cx__W(name, off)
184
185/* GCB register accessor functions */
186BUILD_CM_R_(config, MIPS_CM_GCB_OFS + 0x00)
187BUILD_CM_RW(base, MIPS_CM_GCB_OFS + 0x08)
188BUILD_CM_RW(access, MIPS_CM_GCB_OFS + 0x20)
189BUILD_CM_R_(rev, MIPS_CM_GCB_OFS + 0x30)
190BUILD_CM_RW(err_control, MIPS_CM_GCB_OFS + 0x38)
191BUILD_CM_RW(error_mask, MIPS_CM_GCB_OFS + 0x40)
192BUILD_CM_RW(error_cause, MIPS_CM_GCB_OFS + 0x48)
193BUILD_CM_RW(error_addr, MIPS_CM_GCB_OFS + 0x50)
194BUILD_CM_RW(error_mult, MIPS_CM_GCB_OFS + 0x58)
195BUILD_CM_RW(l2_only_sync_base, MIPS_CM_GCB_OFS + 0x70)
196BUILD_CM_RW(gic_base, MIPS_CM_GCB_OFS + 0x80)
197BUILD_CM_RW(cpc_base, MIPS_CM_GCB_OFS + 0x88)
198BUILD_CM_RW(reg0_base, MIPS_CM_GCB_OFS + 0x90)
199BUILD_CM_RW(reg0_mask, MIPS_CM_GCB_OFS + 0x98)
200BUILD_CM_RW(reg1_base, MIPS_CM_GCB_OFS + 0xa0)
201BUILD_CM_RW(reg1_mask, MIPS_CM_GCB_OFS + 0xa8)
202BUILD_CM_RW(reg2_base, MIPS_CM_GCB_OFS + 0xb0)
203BUILD_CM_RW(reg2_mask, MIPS_CM_GCB_OFS + 0xb8)
204BUILD_CM_RW(reg3_base, MIPS_CM_GCB_OFS + 0xc0)
205BUILD_CM_RW(reg3_mask, MIPS_CM_GCB_OFS + 0xc8)
206BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0)
207BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0)
208BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130)
209BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150)
210BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300)
211BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308)
212BUILD_CM_RW(bev_base, MIPS_CM_GCB_OFS + 0x680)
213
214/* Core Local & Core Other register accessor functions */
215BUILD_CM_Cx_RW(reset_release, 0x00)
216BUILD_CM_Cx_RW(coherence, 0x08)
217BUILD_CM_Cx_R_(config, 0x10)
218BUILD_CM_Cx_RW(other, 0x18)
219BUILD_CM_Cx_RW(reset_base, 0x20)
220BUILD_CM_Cx_R_(id, 0x28)
221BUILD_CM_Cx_RW(reset_ext_base, 0x30)
222BUILD_CM_Cx_R_(tcid_0_priority, 0x40)
223BUILD_CM_Cx_R_(tcid_1_priority, 0x48)
224BUILD_CM_Cx_R_(tcid_2_priority, 0x50)
225BUILD_CM_Cx_R_(tcid_3_priority, 0x58)
226BUILD_CM_Cx_R_(tcid_4_priority, 0x60)
227BUILD_CM_Cx_R_(tcid_5_priority, 0x68)
228BUILD_CM_Cx_R_(tcid_6_priority, 0x70)
229BUILD_CM_Cx_R_(tcid_7_priority, 0x78)
230BUILD_CM_Cx_R_(tcid_8_priority, 0x80)
231
232/* GCR_CONFIG register fields */
233#define CM_GCR_CONFIG_NUMIOCU_SHF 8
234#define CM_GCR_CONFIG_NUMIOCU_MSK (_ULCAST_(0xf) << 8)
235#define CM_GCR_CONFIG_PCORES_SHF 0
236#define CM_GCR_CONFIG_PCORES_MSK (_ULCAST_(0xff) << 0)
237
238/* GCR_BASE register fields */
239#define CM_GCR_BASE_GCRBASE_SHF 15
240#define CM_GCR_BASE_GCRBASE_MSK (_ULCAST_(0x1ffff) << 15)
241#define CM_GCR_BASE_CMDEFTGT_SHF 0
242#define CM_GCR_BASE_CMDEFTGT_MSK (_ULCAST_(0x3) << 0)
243#define CM_GCR_BASE_CMDEFTGT_DISABLED 0 145#define CM_GCR_BASE_CMDEFTGT_DISABLED 0
244#define CM_GCR_BASE_CMDEFTGT_MEM 1 146#define CM_GCR_BASE_CMDEFTGT_MEM 1
245#define CM_GCR_BASE_CMDEFTGT_IOCU0 2 147#define CM_GCR_BASE_CMDEFTGT_IOCU0 2
246#define CM_GCR_BASE_CMDEFTGT_IOCU1 3 148#define CM_GCR_BASE_CMDEFTGT_IOCU1 3
247 149
248/* GCR_RESET_EXT_BASE register fields */ 150/* GCR_ACCESS - Controls core/IOCU access to GCRs */
249#define CM_GCR_RESET_EXT_BASE_EVARESET BIT(31) 151GCR_ACCESSOR_RW(32, 0x020, access)
250#define CM_GCR_RESET_EXT_BASE_UEB BIT(30) 152#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0)
251
252/* GCR_ACCESS register fields */
253#define CM_GCR_ACCESS_ACCESSEN_SHF 0
254#define CM_GCR_ACCESS_ACCESSEN_MSK (_ULCAST_(0xff) << 0)
255 153
256/* GCR_REV register fields */ 154/* GCR_REV - Indicates the Coherence Manager revision */
257#define CM_GCR_REV_MAJOR_SHF 8 155GCR_ACCESSOR_RO(32, 0x030, rev)
258#define CM_GCR_REV_MAJOR_MSK (_ULCAST_(0xff) << 8) 156#define CM_GCR_REV_MAJOR GENMASK(15, 8)
259#define CM_GCR_REV_MINOR_SHF 0 157#define CM_GCR_REV_MINOR GENMASK(7, 0)
260#define CM_GCR_REV_MINOR_MSK (_ULCAST_(0xff) << 0)
261 158
262#define CM_ENCODE_REV(major, minor) \ 159#define CM_ENCODE_REV(major, minor) \
263 (((major) << CM_GCR_REV_MAJOR_SHF) | \ 160 (((major) << __ffs(CM_GCR_REV_MAJOR)) | \
264 ((minor) << CM_GCR_REV_MINOR_SHF)) 161 ((minor) << __ffs(CM_GCR_REV_MINOR)))
265 162
266#define CM_REV_CM2 CM_ENCODE_REV(6, 0) 163#define CM_REV_CM2 CM_ENCODE_REV(6, 0)
267#define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) 164#define CM_REV_CM2_5 CM_ENCODE_REV(7, 0)
268#define CM_REV_CM3 CM_ENCODE_REV(8, 0) 165#define CM_REV_CM3 CM_ENCODE_REV(8, 0)
269 166#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0)
270/* GCR_ERR_CONTROL register fields */ 167
271#define CM_GCR_ERR_CONTROL_L2_ECC_EN_SHF 1 168/* GCR_ERR_CONTROL - Control error checking logic */
272#define CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK (_ULCAST_(0x1) << 1) 169GCR_ACCESSOR_RW(32, 0x038, err_control)
273#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_SHF 0 170#define CM_GCR_ERR_CONTROL_L2_ECC_EN BIT(1)
274#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK (_ULCAST_(0x1) << 0) 171#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT BIT(0)
275 172
276/* GCR_ERROR_CAUSE register fields */ 173/* GCR_ERR_MASK - Control which errors are reported as interrupts */
277#define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27 174GCR_ACCESSOR_RW(64, 0x040, error_mask)
278#define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK (_ULCAST_(0x1f) << 27) 175
279#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF 58 176/* GCR_ERR_CAUSE - Indicates the type of error that occurred */
280#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK GENMASK_ULL(63, 58) 177GCR_ACCESSOR_RW(64, 0x048, error_cause)
281#define CM_GCR_ERROR_CAUSE_ERRINFO_SHF 0 178#define CM_GCR_ERROR_CAUSE_ERRTYPE GENMASK(31, 27)
282#define CM_GCR_ERROR_CAUSE_ERRINGO_MSK (_ULCAST_(0x7ffffff) << 0) 179#define CM3_GCR_ERROR_CAUSE_ERRTYPE GENMASK_ULL(63, 58)
283 180#define CM_GCR_ERROR_CAUSE_ERRINFO GENMASK(26, 0)
284/* GCR_ERROR_MULT register fields */ 181
285#define CM_GCR_ERROR_MULT_ERR2ND_SHF 0 182/* GCR_ERR_ADDR - Indicates the address associated with an error */
286#define CM_GCR_ERROR_MULT_ERR2ND_MSK (_ULCAST_(0x1f) << 0) 183GCR_ACCESSOR_RW(64, 0x050, error_addr)
287 184
288/* GCR_L2_ONLY_SYNC_BASE register fields */ 185/* GCR_ERR_MULT - Indicates when multiple errors have occurred */
289#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_SHF 12 186GCR_ACCESSOR_RW(64, 0x058, error_mult)
290#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK (_ULCAST_(0xfffff) << 12) 187#define CM_GCR_ERROR_MULT_ERR2ND GENMASK(4, 0)
291#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_SHF 0 188
292#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK (_ULCAST_(0x1) << 0) 189/* GCR_L2_ONLY_SYNC_BASE - Base address of the L2 cache-only sync region */
293 190GCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base)
294/* GCR_GIC_BASE register fields */ 191#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE GENMASK(31, 12)
295#define CM_GCR_GIC_BASE_GICBASE_SHF 17 192#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN BIT(0)
296#define CM_GCR_GIC_BASE_GICBASE_MSK (_ULCAST_(0x7fff) << 17) 193
297#define CM_GCR_GIC_BASE_GICEN_SHF 0 194/* GCR_GIC_BASE - Base address of the Global Interrupt Controller (GIC) */
298#define CM_GCR_GIC_BASE_GICEN_MSK (_ULCAST_(0x1) << 0) 195GCR_ACCESSOR_RW(64, 0x080, gic_base)
299 196#define CM_GCR_GIC_BASE_GICBASE GENMASK(31, 17)
300/* GCR_CPC_BASE register fields */ 197#define CM_GCR_GIC_BASE_GICEN BIT(0)
301#define CM_GCR_CPC_BASE_CPCBASE_SHF 15 198
302#define CM_GCR_CPC_BASE_CPCBASE_MSK (_ULCAST_(0x1ffff) << 15) 199/* GCR_CPC_BASE - Base address of the Cluster Power Controller (CPC) */
303#define CM_GCR_CPC_BASE_CPCEN_SHF 0 200GCR_ACCESSOR_RW(64, 0x088, cpc_base)
304#define CM_GCR_CPC_BASE_CPCEN_MSK (_ULCAST_(0x1) << 0) 201#define CM_GCR_CPC_BASE_CPCBASE GENMASK(31, 15)
305 202#define CM_GCR_CPC_BASE_CPCEN BIT(0)
306/* GCR_GIC_STATUS register fields */ 203
307#define CM_GCR_GIC_STATUS_GICEX_SHF 0 204/* GCR_REGn_BASE - Base addresses of CM address regions */
308#define CM_GCR_GIC_STATUS_GICEX_MSK (_ULCAST_(0x1) << 0) 205GCR_ACCESSOR_RW(64, 0x090, reg0_base)
309 206GCR_ACCESSOR_RW(64, 0x0a0, reg1_base)
310/* GCR_REGn_BASE register fields */ 207GCR_ACCESSOR_RW(64, 0x0b0, reg2_base)
311#define CM_GCR_REGn_BASE_BASEADDR_SHF 16 208GCR_ACCESSOR_RW(64, 0x0c0, reg3_base)
312#define CM_GCR_REGn_BASE_BASEADDR_MSK (_ULCAST_(0xffff) << 16) 209#define CM_GCR_REGn_BASE_BASEADDR GENMASK(31, 16)
313 210
314/* GCR_REGn_MASK register fields */ 211/* GCR_REGn_MASK - Size & destination of CM address regions */
315#define CM_GCR_REGn_MASK_ADDRMASK_SHF 16 212GCR_ACCESSOR_RW(64, 0x098, reg0_mask)
316#define CM_GCR_REGn_MASK_ADDRMASK_MSK (_ULCAST_(0xffff) << 16) 213GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask)
317#define CM_GCR_REGn_MASK_CCAOVR_SHF 5 214GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask)
318#define CM_GCR_REGn_MASK_CCAOVR_MSK (_ULCAST_(0x3) << 5) 215GCR_ACCESSOR_RW(64, 0x0c8, reg3_mask)
319#define CM_GCR_REGn_MASK_CCAOVREN_SHF 4 216#define CM_GCR_REGn_MASK_ADDRMASK GENMASK(31, 16)
320#define CM_GCR_REGn_MASK_CCAOVREN_MSK (_ULCAST_(0x1) << 4) 217#define CM_GCR_REGn_MASK_CCAOVR GENMASK(7, 5)
321#define CM_GCR_REGn_MASK_DROPL2_SHF 2 218#define CM_GCR_REGn_MASK_CCAOVREN BIT(4)
322#define CM_GCR_REGn_MASK_DROPL2_MSK (_ULCAST_(0x1) << 2) 219#define CM_GCR_REGn_MASK_DROPL2 BIT(2)
323#define CM_GCR_REGn_MASK_CMTGT_SHF 0 220#define CM_GCR_REGn_MASK_CMTGT GENMASK(1, 0)
324#define CM_GCR_REGn_MASK_CMTGT_MSK (_ULCAST_(0x3) << 0) 221#define CM_GCR_REGn_MASK_CMTGT_DISABLED 0x0
325#define CM_GCR_REGn_MASK_CMTGT_DISABLED (_ULCAST_(0x0) << 0) 222#define CM_GCR_REGn_MASK_CMTGT_MEM 0x1
326#define CM_GCR_REGn_MASK_CMTGT_MEM (_ULCAST_(0x1) << 0) 223#define CM_GCR_REGn_MASK_CMTGT_IOCU0 0x2
327#define CM_GCR_REGn_MASK_CMTGT_IOCU0 (_ULCAST_(0x2) << 0) 224#define CM_GCR_REGn_MASK_CMTGT_IOCU1 0x3
328#define CM_GCR_REGn_MASK_CMTGT_IOCU1 (_ULCAST_(0x3) << 0) 225
329 226/* GCR_GIC_STATUS - Indicates presence of a Global Interrupt Controller (GIC) */
330/* GCR_GIC_STATUS register fields */ 227GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
331#define CM_GCR_GIC_STATUS_EX_SHF 0 228#define CM_GCR_GIC_STATUS_EX BIT(0)
332#define CM_GCR_GIC_STATUS_EX_MSK (_ULCAST_(0x1) << 0) 229
333 230/* GCR_CPC_STATUS - Indicates presence of a Cluster Power Controller (CPC) */
334/* GCR_CPC_STATUS register fields */ 231GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
335#define CM_GCR_CPC_STATUS_EX_SHF 0 232#define CM_GCR_CPC_STATUS_EX BIT(0)
336#define CM_GCR_CPC_STATUS_EX_MSK (_ULCAST_(0x1) << 0) 233
337 234/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */
338/* GCR_L2_CONFIG register fields */ 235GCR_ACCESSOR_RW(32, 0x130, l2_config)
339#define CM_GCR_L2_CONFIG_BYPASS_SHF 20 236#define CM_GCR_L2_CONFIG_BYPASS BIT(20)
340#define CM_GCR_L2_CONFIG_BYPASS_MSK (_ULCAST_(0x1) << 20) 237#define CM_GCR_L2_CONFIG_SET_SIZE GENMASK(15, 12)
341#define CM_GCR_L2_CONFIG_SET_SIZE_SHF 12 238#define CM_GCR_L2_CONFIG_LINE_SIZE GENMASK(11, 8)
342#define CM_GCR_L2_CONFIG_SET_SIZE_MSK (_ULCAST_(0xf) << 12) 239#define CM_GCR_L2_CONFIG_ASSOC GENMASK(7, 0)
343#define CM_GCR_L2_CONFIG_LINE_SIZE_SHF 8 240
344#define CM_GCR_L2_CONFIG_LINE_SIZE_MSK (_ULCAST_(0xf) << 8) 241/* GCR_SYS_CONFIG2 - Further information about the system */
345#define CM_GCR_L2_CONFIG_ASSOC_SHF 0 242GCR_ACCESSOR_RO(32, 0x150, sys_config2)
346#define CM_GCR_L2_CONFIG_ASSOC_MSK (_ULCAST_(0xff) << 0) 243#define CM_GCR_SYS_CONFIG2_MAXVPW GENMASK(3, 0)
347 244
348/* GCR_SYS_CONFIG2 register fields */ 245/* GCR_L2_PFT_CONTROL - Controls hardware L2 prefetching */
349#define CM_GCR_SYS_CONFIG2_MAXVPW_SHF 0 246GCR_ACCESSOR_RW(32, 0x300, l2_pft_control)
350#define CM_GCR_SYS_CONFIG2_MAXVPW_MSK (_ULCAST_(0xf) << 0) 247#define CM_GCR_L2_PFT_CONTROL_PAGEMASK GENMASK(31, 12)
351 248#define CM_GCR_L2_PFT_CONTROL_PFTEN BIT(8)
352/* GCR_L2_PFT_CONTROL register fields */ 249#define CM_GCR_L2_PFT_CONTROL_NPFT GENMASK(7, 0)
353#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF 12 250
354#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK (_ULCAST_(0xfffff) << 12) 251/* GCR_L2_PFT_CONTROL_B - Controls hardware L2 prefetching */
355#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF 8 252GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b)
356#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK (_ULCAST_(0x1) << 8) 253#define CM_GCR_L2_PFT_CONTROL_B_CEN BIT(8)
357#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF 0 254#define CM_GCR_L2_PFT_CONTROL_B_PORTID GENMASK(7, 0)
358#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK (_ULCAST_(0xff) << 0) 255
359 256/* GCR_L2SM_COP - L2 cache op state machine control */
360/* GCR_L2_PFT_CONTROL_B register fields */ 257GCR_ACCESSOR_RW(32, 0x620, l2sm_cop)
361#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF 8 258#define CM_GCR_L2SM_COP_PRESENT BIT(31)
362#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK (_ULCAST_(0x1) << 8) 259#define CM_GCR_L2SM_COP_RESULT GENMASK(8, 6)
363#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF 0 260#define CM_GCR_L2SM_COP_RESULT_DONTCARE 0
364#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK (_ULCAST_(0xff) << 0) 261#define CM_GCR_L2SM_COP_RESULT_DONE_OK 1
365 262#define CM_GCR_L2SM_COP_RESULT_DONE_ERROR 2
366/* GCR_Cx_COHERENCE register fields */ 263#define CM_GCR_L2SM_COP_RESULT_ABORT_OK 3
367#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0 264#define CM_GCR_L2SM_COP_RESULT_ABORT_ERROR 4
368#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0) 265#define CM_GCR_L2SM_COP_RUNNING BIT(5)
369#define CM3_GCR_Cx_COHERENCE_COHEN_MSK (_ULCAST_(0x1) << 0) 266#define CM_GCR_L2SM_COP_TYPE GENMASK(4, 2)
370 267#define CM_GCR_L2SM_COP_TYPE_IDX_WBINV 0
371/* GCR_Cx_CONFIG register fields */ 268#define CM_GCR_L2SM_COP_TYPE_IDX_STORETAG 1
372#define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF 10 269#define CM_GCR_L2SM_COP_TYPE_IDX_STORETAGDATA 2
373#define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK (_ULCAST_(0x3) << 10) 270#define CM_GCR_L2SM_COP_TYPE_HIT_INV 4
374#define CM_GCR_Cx_CONFIG_PVPE_SHF 0 271#define CM_GCR_L2SM_COP_TYPE_HIT_WBINV 5
375#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x3ff) << 0) 272#define CM_GCR_L2SM_COP_TYPE_HIT_WB 6
376 273#define CM_GCR_L2SM_COP_TYPE_FETCHLOCK 7
377/* GCR_Cx_OTHER register fields */ 274#define CM_GCR_L2SM_COP_CMD GENMASK(1, 0)
378#define CM_GCR_Cx_OTHER_CORENUM_SHF 16 275#define CM_GCR_L2SM_COP_CMD_START 1 /* only when idle */
379#define CM_GCR_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xffff) << 16) 276#define CM_GCR_L2SM_COP_CMD_ABORT 3 /* only when running */
380#define CM3_GCR_Cx_OTHER_CORE_SHF 8 277
381#define CM3_GCR_Cx_OTHER_CORE_MSK (_ULCAST_(0x3f) << 8) 278/* GCR_L2SM_TAG_ADDR_COP - L2 cache op state machine address control */
382#define CM3_GCR_Cx_OTHER_VP_SHF 0 279GCR_ACCESSOR_RW(64, 0x628, l2sm_tag_addr_cop)
383#define CM3_GCR_Cx_OTHER_VP_MSK (_ULCAST_(0x7) << 0) 280#define CM_GCR_L2SM_TAG_ADDR_COP_NUM_LINES GENMASK_ULL(63, 48)
384 281#define CM_GCR_L2SM_TAG_ADDR_COP_START_TAG GENMASK_ULL(47, 6)
385/* GCR_Cx_RESET_BASE register fields */ 282
386#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF 12 283/* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */
387#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_MSK (_ULCAST_(0xfffff) << 12) 284GCR_ACCESSOR_RW(64, 0x680, bev_base)
388 285
389/* GCR_Cx_RESET_EXT_BASE register fields */ 286/* GCR_Cx_RESET_RELEASE - Controls core reset for CM 1.x */
390#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_SHF 31 287GCR_CX_ACCESSOR_RW(32, 0x000, reset_release)
391#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_MSK (_ULCAST_(0x1) << 31) 288
392#define CM_GCR_Cx_RESET_EXT_BASE_UEB_SHF 30 289/* GCR_Cx_COHERENCE - Controls core coherence */
393#define CM_GCR_Cx_RESET_EXT_BASE_UEB_MSK (_ULCAST_(0x1) << 30) 290GCR_CX_ACCESSOR_RW(32, 0x008, coherence)
394#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_SHF 20 291#define CM_GCR_Cx_COHERENCE_COHDOMAINEN GENMASK(7, 0)
395#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_MSK (_ULCAST_(0xff) << 20) 292#define CM3_GCR_Cx_COHERENCE_COHEN BIT(0)
396#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_SHF 1 293
397#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_MSK (_ULCAST_(0x7f) << 1) 294/* GCR_Cx_CONFIG - Information about a core's configuration */
398#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_SHF 0 295GCR_CX_ACCESSOR_RO(32, 0x010, config)
399#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_MSK (_ULCAST_(0x1) << 0) 296#define CM_GCR_Cx_CONFIG_IOCUTYPE GENMASK(11, 10)
400 297#define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0)
401/** 298
402 * mips_cm_numcores - return the number of cores present in the system 299/* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */
403 * 300GCR_CX_ACCESSOR_RW(32, 0x018, other)
404 * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or 301#define CM_GCR_Cx_OTHER_CORENUM GENMASK(31, 16) /* CM < 3 */
405 * zero if no Coherence Manager is present. 302#define CM_GCR_Cx_OTHER_CLUSTER_EN BIT(31) /* CM >= 3.5 */
406 */ 303#define CM_GCR_Cx_OTHER_GIC_EN BIT(30) /* CM >= 3.5 */
407static inline unsigned mips_cm_numcores(void) 304#define CM_GCR_Cx_OTHER_BLOCK GENMASK(25, 24) /* CM >= 3.5 */
408{ 305#define CM_GCR_Cx_OTHER_BLOCK_LOCAL 0
409 if (!mips_cm_present()) 306#define CM_GCR_Cx_OTHER_BLOCK_GLOBAL 1
410 return 0; 307#define CM_GCR_Cx_OTHER_BLOCK_USER 2
411 308#define CM_GCR_Cx_OTHER_BLOCK_GLOBAL_HIGH 3
412 return ((read_gcr_config() & CM_GCR_CONFIG_PCORES_MSK) 309#define CM_GCR_Cx_OTHER_CLUSTER GENMASK(21, 16) /* CM >= 3.5 */
413 >> CM_GCR_CONFIG_PCORES_SHF) + 1; 310#define CM3_GCR_Cx_OTHER_CORE GENMASK(13, 8) /* CM >= 3 */
414} 311#define CM_GCR_Cx_OTHER_CORE_CM 32
415 312#define CM3_GCR_Cx_OTHER_VP GENMASK(2, 0) /* CM >= 3 */
416/** 313
417 * mips_cm_numiocu - return the number of IOCUs present in the system 314/* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */
418 * 315GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
419 * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero 316#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE GENMASK(31, 12)
420 * if no Coherence Manager is present. 317
421 */ 318/* GCR_Cx_ID - Identify the current core */
422static inline unsigned mips_cm_numiocu(void) 319GCR_CX_ACCESSOR_RO(32, 0x028, id)
423{ 320#define CM_GCR_Cx_ID_CLUSTER GENMASK(15, 8)
424 if (!mips_cm_present()) 321#define CM_GCR_Cx_ID_CORE GENMASK(7, 0)
425 return 0; 322
426 323/* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */
427 return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU_MSK) 324GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
428 >> CM_GCR_CONFIG_NUMIOCU_SHF; 325#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET BIT(31)
429} 326#define CM_GCR_Cx_RESET_EXT_BASE_UEB BIT(30)
327#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK GENMASK(27, 20)
328#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA GENMASK(7, 1)
329#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT BIT(0)
430 330
431/** 331/**
432 * mips_cm_l2sync - perform an L2-only sync operation 332 * mips_cm_l2sync - perform an L2-only sync operation
@@ -469,7 +369,7 @@ static inline unsigned int mips_cm_max_vp_width(void)
469 uint32_t cfg; 369 uint32_t cfg;
470 370
471 if (mips_cm_revision() >= CM_REV_CM3) 371 if (mips_cm_revision() >= CM_REV_CM3)
472 return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW_MSK; 372 return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW;
473 373
474 if (mips_cm_present()) { 374 if (mips_cm_present()) {
475 /* 375 /*
@@ -477,8 +377,8 @@ static inline unsigned int mips_cm_max_vp_width(void)
477 * number of VP(E)s, and if that ever changes then this will 377 * number of VP(E)s, and if that ever changes then this will
478 * need revisiting. 378 * need revisiting.
479 */ 379 */
480 cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE_MSK; 380 cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE;
481 return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1; 381 return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1;
482 } 382 }
483 383
484 if (IS_ENABLED(CONFIG_SMP)) 384 if (IS_ENABLED(CONFIG_SMP))
@@ -499,7 +399,7 @@ static inline unsigned int mips_cm_max_vp_width(void)
499 */ 399 */
500static inline unsigned int mips_cm_vp_id(unsigned int cpu) 400static inline unsigned int mips_cm_vp_id(unsigned int cpu)
501{ 401{
502 unsigned int core = cpu_data[cpu].core; 402 unsigned int core = cpu_core(&cpu_data[cpu]);
503 unsigned int vp = cpu_vpe_id(&cpu_data[cpu]); 403 unsigned int vp = cpu_vpe_id(&cpu_data[cpu]);
504 404
505 return (core * mips_cm_max_vp_width()) + vp; 405 return (core * mips_cm_max_vp_width()) + vp;
@@ -508,29 +408,56 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu)
508#ifdef CONFIG_MIPS_CM 408#ifdef CONFIG_MIPS_CM
509 409
510/** 410/**
511 * mips_cm_lock_other - lock access to another core 411 * mips_cm_lock_other - lock access to redirect/other region
412 * @cluster: the other cluster to be accessed
512 * @core: the other core to be accessed 413 * @core: the other core to be accessed
513 * @vp: the VP within the other core to be accessed 414 * @vp: the VP within the other core to be accessed
415 * @block: the register block to be accessed
514 * 416 *
515 * Call before operating upon a core via the 'other' register region in 417 * Configure the redirect/other region for the local core/VP (depending upon
516 * order to prevent the region being moved during access. Must be followed 418 * the CM revision) to target the specified @cluster, @core, @vp & register
517 * by a call to mips_cm_unlock_other. 419 * @block. Must be called before using the redirect/other region, and followed
420 * by a call to mips_cm_unlock_other() when access to the redirect/other region
421 * is complete.
422 *
423 * This function acquires a spinlock such that code between it &
424 * mips_cm_unlock_other() calls cannot be pre-empted by anything which may
425 * reconfigure the redirect/other region, and cannot be interfered with by
426 * another VP in the core. As such calls to this function should not be nested.
518 */ 427 */
519extern void mips_cm_lock_other(unsigned int core, unsigned int vp); 428extern void mips_cm_lock_other(unsigned int cluster, unsigned int core,
429 unsigned int vp, unsigned int block);
520 430
521/** 431/**
522 * mips_cm_unlock_other - unlock access to another core 432 * mips_cm_unlock_other - unlock access to redirect/other region
523 * 433 *
524 * Call after operating upon another core via the 'other' register region. 434 * Must be called after mips_cm_lock_other() once all required access to the
525 * Must be called after mips_cm_lock_other. 435 * redirect/other region has been completed.
526 */ 436 */
527extern void mips_cm_unlock_other(void); 437extern void mips_cm_unlock_other(void);
528 438
529#else /* !CONFIG_MIPS_CM */ 439#else /* !CONFIG_MIPS_CM */
530 440
531static inline void mips_cm_lock_other(unsigned int core, unsigned int vp) { } 441static inline void mips_cm_lock_other(unsigned int cluster, unsigned int core,
442 unsigned int vp, unsigned int block) { }
532static inline void mips_cm_unlock_other(void) { } 443static inline void mips_cm_unlock_other(void) { }
533 444
534#endif /* !CONFIG_MIPS_CM */ 445#endif /* !CONFIG_MIPS_CM */
535 446
447/**
448 * mips_cm_lock_other_cpu - lock access to redirect/other region
449 * @cpu: the other CPU whose register we want to access
450 *
451 * Configure the redirect/other region for the local core/VP (depending upon
452 * the CM revision) to target the specified @cpu & register @block. This is
453 * equivalent to calling mips_cm_lock_other() but accepts a Linux CPU number
454 * for convenience.
455 */
456static inline void mips_cm_lock_other_cpu(unsigned int cpu, unsigned int block)
457{
458 struct cpuinfo_mips *d = &cpu_data[cpu];
459
460 mips_cm_lock_other(cpu_cluster(d), cpu_core(d), cpu_vpe_id(d), block);
461}
462
536#endif /* __MIPS_ASM_MIPS_CM_H__ */ 463#endif /* __MIPS_ASM_MIPS_CM_H__ */
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 8c519f9827a3..f885051a8378 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -8,11 +8,15 @@
8 * option) any later version. 8 * option) any later version.
9 */ 9 */
10 10
11#ifndef __MIPS_ASM_MIPS_CPS_H__
12# error Please include asm/mips-cps.h rather than asm/mips-cpc.h
13#endif
14
11#ifndef __MIPS_ASM_MIPS_CPC_H__ 15#ifndef __MIPS_ASM_MIPS_CPC_H__
12#define __MIPS_ASM_MIPS_CPC_H__ 16#define __MIPS_ASM_MIPS_CPC_H__
13 17
14#include <linux/io.h> 18#include <linux/bitops.h>
15#include <linux/types.h> 19#include <linux/errno.h>
16 20
17/* The base address of the CPC registers */ 21/* The base address of the CPC registers */
18extern void __iomem *mips_cpc_base; 22extern void __iomem *mips_cpc_base;
@@ -61,89 +65,92 @@ static inline bool mips_cpc_present(void)
61#define MIPS_CPC_CLCB_OFS 0x2000 65#define MIPS_CPC_CLCB_OFS 0x2000
62#define MIPS_CPC_COCB_OFS 0x4000 66#define MIPS_CPC_COCB_OFS 0x4000
63 67
64/* Macros to ease the creation of register access functions */ 68#define CPC_ACCESSOR_RO(sz, off, name) \
65#define BUILD_CPC_R_(name, off) \ 69 CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name) \
66static inline u32 *addr_cpc_##name(void) \ 70 CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name)
67{ \ 71
68 return (u32 *)(mips_cpc_base + (off)); \ 72#define CPC_ACCESSOR_RW(sz, off, name) \
69} \ 73 CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name) \
70 \ 74 CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name)
71static inline u32 read_cpc_##name(void) \ 75
72{ \ 76#define CPC_CX_ACCESSOR_RO(sz, off, name) \
73 return __raw_readl(mips_cpc_base + (off)); \ 77 CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name) \
74} 78 CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
75 79
76#define BUILD_CPC__W(name, off) \ 80#define CPC_CX_ACCESSOR_RW(sz, off, name) \
77static inline void write_cpc_##name(u32 value) \ 81 CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name) \
78{ \ 82 CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
79 __raw_writel(value, mips_cpc_base + (off)); \ 83
80} 84/* CPC_ACCESS - Control core/IOCU access to CPC registers prior to CM 3 */
81 85CPC_ACCESSOR_RW(32, 0x000, access)
82#define BUILD_CPC_RW(name, off) \ 86
83 BUILD_CPC_R_(name, off) \ 87/* CPC_SEQDEL - Configure delays between command sequencer steps */
84 BUILD_CPC__W(name, off) 88CPC_ACCESSOR_RW(32, 0x008, seqdel)
85 89
86#define BUILD_CPC_Cx_R_(name, off) \ 90/* CPC_RAIL - Configure the delay from rail power-up to stability */
87 BUILD_CPC_R_(cl_##name, MIPS_CPC_CLCB_OFS + (off)) \ 91CPC_ACCESSOR_RW(32, 0x010, rail)
88 BUILD_CPC_R_(co_##name, MIPS_CPC_COCB_OFS + (off)) 92
89 93/* CPC_RESETLEN - Configure the length of reset sequences */
90#define BUILD_CPC_Cx__W(name, off) \ 94CPC_ACCESSOR_RW(32, 0x018, resetlen)
91 BUILD_CPC__W(cl_##name, MIPS_CPC_CLCB_OFS + (off)) \ 95
92 BUILD_CPC__W(co_##name, MIPS_CPC_COCB_OFS + (off)) 96/* CPC_REVISION - Indicates the revisison of the CPC */
93 97CPC_ACCESSOR_RO(32, 0x020, revision)
94#define BUILD_CPC_Cx_RW(name, off) \ 98
95 BUILD_CPC_Cx_R_(name, off) \ 99/* CPC_PWRUP_CTL - Control power to the Coherence Manager (CM) */
96 BUILD_CPC_Cx__W(name, off) 100CPC_ACCESSOR_RW(32, 0x030, pwrup_ctl)
97 101#define CPC_PWRUP_CTL_CM_PWRUP BIT(0)
98/* GCB register accessor functions */ 102
99BUILD_CPC_RW(access, MIPS_CPC_GCB_OFS + 0x00) 103/* CPC_CONFIG - Mirrors GCR_CONFIG */
100BUILD_CPC_RW(seqdel, MIPS_CPC_GCB_OFS + 0x08) 104CPC_ACCESSOR_RW(64, 0x138, config)
101BUILD_CPC_RW(rail, MIPS_CPC_GCB_OFS + 0x10) 105
102BUILD_CPC_RW(resetlen, MIPS_CPC_GCB_OFS + 0x18) 106/* CPC_SYS_CONFIG - Control cluster endianness */
103BUILD_CPC_R_(revision, MIPS_CPC_GCB_OFS + 0x20) 107CPC_ACCESSOR_RW(32, 0x140, sys_config)
104 108#define CPC_SYS_CONFIG_BE_IMMEDIATE BIT(2)
105/* Core Local & Core Other accessor functions */ 109#define CPC_SYS_CONFIG_BE_STATUS BIT(1)
106BUILD_CPC_Cx_RW(cmd, 0x00) 110#define CPC_SYS_CONFIG_BE BIT(0)
107BUILD_CPC_Cx_RW(stat_conf, 0x08) 111
108BUILD_CPC_Cx_RW(other, 0x10) 112/* CPC_Cx_CMD - Instruct the CPC to take action on a core */
109BUILD_CPC_Cx_RW(vp_stop, 0x20) 113CPC_CX_ACCESSOR_RW(32, 0x000, cmd)
110BUILD_CPC_Cx_RW(vp_run, 0x28) 114#define CPC_Cx_CMD GENMASK(3, 0)
111BUILD_CPC_Cx_RW(vp_running, 0x30) 115#define CPC_Cx_CMD_CLOCKOFF 0x1
112 116#define CPC_Cx_CMD_PWRDOWN 0x2
113/* CPC_Cx_CMD register fields */ 117#define CPC_Cx_CMD_PWRUP 0x3
114#define CPC_Cx_CMD_SHF 0 118#define CPC_Cx_CMD_RESET 0x4
115#define CPC_Cx_CMD_MSK (_ULCAST_(0xf) << 0) 119
116#define CPC_Cx_CMD_CLOCKOFF (_ULCAST_(0x1) << 0) 120/* CPC_Cx_STAT_CONF - Indicates core configuration & state */
117#define CPC_Cx_CMD_PWRDOWN (_ULCAST_(0x2) << 0) 121CPC_CX_ACCESSOR_RW(32, 0x008, stat_conf)
118#define CPC_Cx_CMD_PWRUP (_ULCAST_(0x3) << 0) 122#define CPC_Cx_STAT_CONF_PWRUPE BIT(23)
119#define CPC_Cx_CMD_RESET (_ULCAST_(0x4) << 0) 123#define CPC_Cx_STAT_CONF_SEQSTATE GENMASK(22, 19)
120 124#define CPC_Cx_STAT_CONF_SEQSTATE_D0 0x0
121/* CPC_Cx_STAT_CONF register fields */ 125#define CPC_Cx_STAT_CONF_SEQSTATE_U0 0x1
122#define CPC_Cx_STAT_CONF_PWRUPE_SHF 23 126#define CPC_Cx_STAT_CONF_SEQSTATE_U1 0x2
123#define CPC_Cx_STAT_CONF_PWRUPE_MSK (_ULCAST_(0x1) << 23) 127#define CPC_Cx_STAT_CONF_SEQSTATE_U2 0x3
124#define CPC_Cx_STAT_CONF_SEQSTATE_SHF 19 128#define CPC_Cx_STAT_CONF_SEQSTATE_U3 0x4
125#define CPC_Cx_STAT_CONF_SEQSTATE_MSK (_ULCAST_(0xf) << 19) 129#define CPC_Cx_STAT_CONF_SEQSTATE_U4 0x5
126#define CPC_Cx_STAT_CONF_SEQSTATE_D0 (_ULCAST_(0x0) << 19) 130#define CPC_Cx_STAT_CONF_SEQSTATE_U5 0x6
127#define CPC_Cx_STAT_CONF_SEQSTATE_U0 (_ULCAST_(0x1) << 19) 131#define CPC_Cx_STAT_CONF_SEQSTATE_U6 0x7
128#define CPC_Cx_STAT_CONF_SEQSTATE_U1 (_ULCAST_(0x2) << 19) 132#define CPC_Cx_STAT_CONF_SEQSTATE_D1 0x8
129#define CPC_Cx_STAT_CONF_SEQSTATE_U2 (_ULCAST_(0x3) << 19) 133#define CPC_Cx_STAT_CONF_SEQSTATE_D3 0x9
130#define CPC_Cx_STAT_CONF_SEQSTATE_U3 (_ULCAST_(0x4) << 19) 134#define CPC_Cx_STAT_CONF_SEQSTATE_D2 0xa
131#define CPC_Cx_STAT_CONF_SEQSTATE_U4 (_ULCAST_(0x5) << 19) 135#define CPC_Cx_STAT_CONF_CLKGAT_IMPL BIT(17)
132#define CPC_Cx_STAT_CONF_SEQSTATE_U5 (_ULCAST_(0x6) << 19) 136#define CPC_Cx_STAT_CONF_PWRDN_IMPL BIT(16)
133#define CPC_Cx_STAT_CONF_SEQSTATE_U6 (_ULCAST_(0x7) << 19) 137#define CPC_Cx_STAT_CONF_EJTAG_PROBE BIT(15)
134#define CPC_Cx_STAT_CONF_SEQSTATE_D1 (_ULCAST_(0x8) << 19) 138
135#define CPC_Cx_STAT_CONF_SEQSTATE_D3 (_ULCAST_(0x9) << 19) 139/* CPC_Cx_OTHER - Configure the core-other register block prior to CM 3 */
136#define CPC_Cx_STAT_CONF_SEQSTATE_D2 (_ULCAST_(0xa) << 19) 140CPC_CX_ACCESSOR_RW(32, 0x010, other)
137#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_SHF 17 141#define CPC_Cx_OTHER_CORENUM GENMASK(23, 16)
138#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK (_ULCAST_(0x1) << 17) 142
139#define CPC_Cx_STAT_CONF_PWRDN_IMPL_SHF 16 143/* CPC_Cx_VP_STOP - Stop Virtual Processors (VPs) within a core from running */
140#define CPC_Cx_STAT_CONF_PWRDN_IMPL_MSK (_ULCAST_(0x1) << 16) 144CPC_CX_ACCESSOR_RW(32, 0x020, vp_stop)
141#define CPC_Cx_STAT_CONF_EJTAG_PROBE_SHF 15 145
142#define CPC_Cx_STAT_CONF_EJTAG_PROBE_MSK (_ULCAST_(0x1) << 15) 146/* CPC_Cx_VP_START - Start Virtual Processors (VPs) within a core running */
143 147CPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
144/* CPC_Cx_OTHER register fields */ 148
145#define CPC_Cx_OTHER_CORENUM_SHF 16 149/* CPC_Cx_VP_RUNNING - Indicate which Virtual Processors (VPs) are running */
146#define CPC_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xff) << 16) 150CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
151
152/* CPC_Cx_CONFIG - Mirrors GCR_Cx_CONFIG */
153CPC_CX_ACCESSOR_RW(32, 0x090, config)
147 154
148#ifdef CONFIG_MIPS_CPC 155#ifdef CONFIG_MIPS_CPC
149 156
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
new file mode 100644
index 000000000000..bf02b5070a98
--- /dev/null
+++ b/arch/mips/include/asm/mips-cps.h
@@ -0,0 +1,240 @@
1/*
2 * Copyright (C) 2017 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __MIPS_ASM_MIPS_CPS_H__
12#define __MIPS_ASM_MIPS_CPS_H__
13
14#include <linux/io.h>
15#include <linux/types.h>
16
17extern unsigned long __cps_access_bad_size(void)
18 __compiletime_error("Bad size for CPS accessor");
19
20#define CPS_ACCESSOR_A(unit, off, name) \
21static inline void *addr_##unit##_##name(void) \
22{ \
23 return mips_##unit##_base + (off); \
24}
25
26#define CPS_ACCESSOR_R(unit, sz, name) \
27static inline uint##sz##_t read_##unit##_##name(void) \
28{ \
29 uint64_t val64; \
30 \
31 switch (sz) { \
32 case 32: \
33 return __raw_readl(addr_##unit##_##name()); \
34 \
35 case 64: \
36 if (mips_cm_is64) \
37 return __raw_readq(addr_##unit##_##name()); \
38 \
39 val64 = __raw_readl(addr_##unit##_##name() + 4); \
40 val64 <<= 32; \
41 val64 |= __raw_readl(addr_##unit##_##name()); \
42 return val64; \
43 \
44 default: \
45 return __cps_access_bad_size(); \
46 } \
47}
48
49#define CPS_ACCESSOR_W(unit, sz, name) \
50static inline void write_##unit##_##name(uint##sz##_t val) \
51{ \
52 switch (sz) { \
53 case 32: \
54 __raw_writel(val, addr_##unit##_##name()); \
55 break; \
56 \
57 case 64: \
58 if (mips_cm_is64) { \
59 __raw_writeq(val, addr_##unit##_##name()); \
60 break; \
61 } \
62 \
63 __raw_writel((uint64_t)val >> 32, \
64 addr_##unit##_##name() + 4); \
65 __raw_writel(val, addr_##unit##_##name()); \
66 break; \
67 \
68 default: \
69 __cps_access_bad_size(); \
70 break; \
71 } \
72}
73
74#define CPS_ACCESSOR_M(unit, sz, name) \
75static inline void change_##unit##_##name(uint##sz##_t mask, \
76 uint##sz##_t val) \
77{ \
78 uint##sz##_t reg_val = read_##unit##_##name(); \
79 reg_val &= ~mask; \
80 reg_val |= val; \
81 write_##unit##_##name(reg_val); \
82} \
83 \
84static inline void set_##unit##_##name(uint##sz##_t val) \
85{ \
86 change_##unit##_##name(val, val); \
87} \
88 \
89static inline void clear_##unit##_##name(uint##sz##_t val) \
90{ \
91 change_##unit##_##name(val, 0); \
92}
93
94#define CPS_ACCESSOR_RO(unit, sz, off, name) \
95 CPS_ACCESSOR_A(unit, off, name) \
96 CPS_ACCESSOR_R(unit, sz, name)
97
98#define CPS_ACCESSOR_WO(unit, sz, off, name) \
99 CPS_ACCESSOR_A(unit, off, name) \
100 CPS_ACCESSOR_W(unit, sz, name)
101
102#define CPS_ACCESSOR_RW(unit, sz, off, name) \
103 CPS_ACCESSOR_A(unit, off, name) \
104 CPS_ACCESSOR_R(unit, sz, name) \
105 CPS_ACCESSOR_W(unit, sz, name) \
106 CPS_ACCESSOR_M(unit, sz, name)
107
108#include <asm/mips-cm.h>
109#include <asm/mips-cpc.h>
110#include <asm/mips-gic.h>
111
112/**
113 * mips_cps_numclusters - return the number of clusters present in the system
114 *
115 * Returns the number of clusters in the system.
116 */
117static inline unsigned int mips_cps_numclusters(void)
118{
119 unsigned int num_clusters;
120
121 if (mips_cm_revision() < CM_REV_CM3_5)
122 return 1;
123
124 num_clusters = read_gcr_config() & CM_GCR_CONFIG_NUM_CLUSTERS;
125 num_clusters >>= __ffs(CM_GCR_CONFIG_NUM_CLUSTERS);
126 return num_clusters;
127}
128
129/**
130 * mips_cps_cluster_config - return (GCR|CPC)_CONFIG from a cluster
131 * @cluster: the ID of the cluster whose config we want
132 *
133 * Read the value of GCR_CONFIG (or its CPC_CONFIG mirror) from a @cluster.
134 *
135 * Returns the value of GCR_CONFIG.
136 */
137static inline uint64_t mips_cps_cluster_config(unsigned int cluster)
138{
139 uint64_t config;
140
141 if (mips_cm_revision() < CM_REV_CM3_5) {
142 /*
143 * Prior to CM 3.5 we don't have the notion of multiple
144 * clusters so we can trivially read the GCR_CONFIG register
145 * within this cluster.
146 */
147 WARN_ON(cluster != 0);
148 config = read_gcr_config();
149 } else {
150 /*
151 * From CM 3.5 onwards we read the CPC_CONFIG mirror of
152 * GCR_CONFIG via the redirect region, since the CPC is always
153 * powered up allowing us not to need to power up the CM.
154 */
155 mips_cm_lock_other(cluster, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL);
156 config = read_cpc_redir_config();
157 mips_cm_unlock_other();
158 }
159
160 return config;
161}
162
163/**
164 * mips_cps_numcores - return the number of cores present in a cluster
165 * @cluster: the ID of the cluster whose core count we want
166 *
167 * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or
168 * zero if no Coherence Manager is present.
169 */
170static inline unsigned int mips_cps_numcores(unsigned int cluster)
171{
172 if (!mips_cm_present())
173 return 0;
174
175 /* Add one before masking to handle 0xff indicating no cores */
176 return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
177}
178
179/**
180 * mips_cps_numiocu - return the number of IOCUs present in a cluster
181 * @cluster: the ID of the cluster whose IOCU count we want
182 *
183 * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero
184 * if no Coherence Manager is present.
185 */
186static inline unsigned int mips_cps_numiocu(unsigned int cluster)
187{
188 unsigned int num_iocu;
189
190 if (!mips_cm_present())
191 return 0;
192
193 num_iocu = mips_cps_cluster_config(cluster) & CM_GCR_CONFIG_NUMIOCU;
194 num_iocu >>= __ffs(CM_GCR_CONFIG_NUMIOCU);
195 return num_iocu;
196}
197
198/**
199 * mips_cps_numvps - return the number of VPs (threads) supported by a core
200 * @cluster: the ID of the cluster containing the core we want to examine
201 * @core: the ID of the core whose VP count we want
202 *
203 * Returns the number of Virtual Processors (VPs, ie. hardware threads) that
204 * are supported by the given @core in the given @cluster. If the core or the
205 * kernel do not support hardware mutlti-threading this returns 1.
206 */
207static inline unsigned int mips_cps_numvps(unsigned int cluster, unsigned int core)
208{
209 unsigned int cfg;
210
211 if (!mips_cm_present())
212 return 1;
213
214 if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt)
215 && (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp))
216 return 1;
217
218 mips_cm_lock_other(cluster, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
219
220 if (mips_cm_revision() < CM_REV_CM3_5) {
221 /*
222 * Prior to CM 3.5 we can only have one cluster & don't have
223 * CPC_Cx_CONFIG, so we read GCR_Cx_CONFIG.
224 */
225 cfg = read_gcr_co_config();
226 } else {
227 /*
228 * From CM 3.5 onwards we read CPC_Cx_CONFIG because the CPC is
229 * always powered, which allows us to not worry about powering
230 * up the cluster's CM here.
231 */
232 cfg = read_cpc_co_config();
233 }
234
235 mips_cm_unlock_other();
236
237 return (cfg + 1) & CM_GCR_Cx_CONFIG_PVPE;
238}
239
240#endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h
new file mode 100644
index 000000000000..a2badf572632
--- /dev/null
+++ b/arch/mips/include/asm/mips-gic.h
@@ -0,0 +1,347 @@
1/*
2 * Copyright (C) 2017 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __MIPS_ASM_MIPS_CPS_H__
12# error Please include asm/mips-cps.h rather than asm/mips-gic.h
13#endif
14
15#ifndef __MIPS_ASM_MIPS_GIC_H__
16#define __MIPS_ASM_MIPS_GIC_H__
17
18#include <linux/bitops.h>
19
20/* The base address of the GIC registers */
21extern void __iomem *mips_gic_base;
22
23/* Offsets from the GIC base address to various control blocks */
24#define MIPS_GIC_SHARED_OFS 0x00000
25#define MIPS_GIC_SHARED_SZ 0x08000
26#define MIPS_GIC_LOCAL_OFS 0x08000
27#define MIPS_GIC_LOCAL_SZ 0x04000
28#define MIPS_GIC_REDIR_OFS 0x0c000
29#define MIPS_GIC_REDIR_SZ 0x04000
30#define MIPS_GIC_USER_OFS 0x10000
31#define MIPS_GIC_USER_SZ 0x10000
32
33/* For read-only shared registers */
34#define GIC_ACCESSOR_RO(sz, off, name) \
35 CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
36
37/* For read-write shared registers */
38#define GIC_ACCESSOR_RW(sz, off, name) \
39 CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
40
41/* For read-only local registers */
42#define GIC_VX_ACCESSOR_RO(sz, off, name) \
43 CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name) \
44 CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
45
46/* For read-write local registers */
47#define GIC_VX_ACCESSOR_RW(sz, off, name) \
48 CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name) \
49 CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
50
51/* For read-only shared per-interrupt registers */
52#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
53static inline void __iomem *addr_gic_##name(unsigned int intr) \
54{ \
55 return mips_gic_base + (off) + (intr * (stride)); \
56} \
57 \
58static inline unsigned int read_gic_##name(unsigned int intr) \
59{ \
60 BUILD_BUG_ON(sz != 32); \
61 return __raw_readl(addr_gic_##name(intr)); \
62}
63
64/* For read-write shared per-interrupt registers */
65#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \
66 GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
67 \
68static inline void write_gic_##name(unsigned int intr, \
69 unsigned int val) \
70{ \
71 BUILD_BUG_ON(sz != 32); \
72 __raw_writel(val, addr_gic_##name(intr)); \
73}
74
75/* For read-only local per-interrupt registers */
76#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \
77 GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \
78 stride, vl_##name) \
79 GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \
80 stride, vo_##name)
81
82/* For read-write local per-interrupt registers */
83#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \
84 GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \
85 stride, vl_##name) \
86 GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \
87 stride, vo_##name)
88
89/* For read-only shared bit-per-interrupt registers */
90#define GIC_ACCESSOR_RO_INTR_BIT(off, name) \
91static inline void __iomem *addr_gic_##name(void) \
92{ \
93 return mips_gic_base + (off); \
94} \
95 \
96static inline unsigned int read_gic_##name(unsigned int intr) \
97{ \
98 void __iomem *addr = addr_gic_##name(); \
99 unsigned int val; \
100 \
101 if (mips_cm_is64) { \
102 addr += (intr / 64) * sizeof(uint64_t); \
103 val = __raw_readq(addr) >> intr % 64; \
104 } else { \
105 addr += (intr / 32) * sizeof(uint32_t); \
106 val = __raw_readl(addr) >> intr % 32; \
107 } \
108 \
109 return val & 0x1; \
110}
111
112/* For read-write shared bit-per-interrupt registers */
113#define GIC_ACCESSOR_RW_INTR_BIT(off, name) \
114 GIC_ACCESSOR_RO_INTR_BIT(off, name) \
115 \
116static inline void write_gic_##name(unsigned int intr) \
117{ \
118 void __iomem *addr = addr_gic_##name(); \
119 \
120 if (mips_cm_is64) { \
121 addr += (intr / 64) * sizeof(uint64_t); \
122 __raw_writeq(BIT(intr % 64), addr); \
123 } else { \
124 addr += (intr / 32) * sizeof(uint32_t); \
125 __raw_writel(BIT(intr % 32), addr); \
126 } \
127} \
128 \
129static inline void change_gic_##name(unsigned int intr, \
130 unsigned int val) \
131{ \
132 void __iomem *addr = addr_gic_##name(); \
133 \
134 if (mips_cm_is64) { \
135 uint64_t _val; \
136 \
137 addr += (intr / 64) * sizeof(uint64_t); \
138 _val = __raw_readq(addr); \
139 _val &= ~BIT_ULL(intr % 64); \
140 _val |= (uint64_t)val << (intr % 64); \
141 __raw_writeq(_val, addr); \
142 } else { \
143 uint32_t _val; \
144 \
145 addr += (intr / 32) * sizeof(uint32_t); \
146 _val = __raw_readl(addr); \
147 _val &= ~BIT(intr % 32); \
148 _val |= val << (intr % 32); \
149 __raw_writel(_val, addr); \
150 } \
151}
152
153/* For read-only local bit-per-interrupt registers */
154#define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name) \
155 GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \
156 vl_##name) \
157 GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off, \
158 vo_##name)
159
160/* For read-write local bit-per-interrupt registers */
161#define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name) \
162 GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \
163 vl_##name) \
164 GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off, \
165 vo_##name)
166
167/* GIC_SH_CONFIG - Information about the GIC configuration */
168GIC_ACCESSOR_RW(32, 0x000, config)
169#define GIC_CONFIG_COUNTSTOP BIT(28)
170#define GIC_CONFIG_COUNTBITS GENMASK(27, 24)
171#define GIC_CONFIG_NUMINTERRUPTS GENMASK(23, 16)
172#define GIC_CONFIG_PVPS GENMASK(6, 0)
173
174/* GIC_SH_COUNTER - Shared global counter value */
175GIC_ACCESSOR_RW(64, 0x010, counter)
176GIC_ACCESSOR_RW(32, 0x010, counter_32l)
177GIC_ACCESSOR_RW(32, 0x014, counter_32h)
178
179/* GIC_SH_POL_* - Configures interrupt polarity */
180GIC_ACCESSOR_RW_INTR_BIT(0x100, pol)
181#define GIC_POL_ACTIVE_LOW 0 /* when level triggered */
182#define GIC_POL_ACTIVE_HIGH 1 /* when level triggered */
183#define GIC_POL_FALLING_EDGE 0 /* when single-edge triggered */
184#define GIC_POL_RISING_EDGE 1 /* when single-edge triggered */
185
186/* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */
187GIC_ACCESSOR_RW_INTR_BIT(0x180, trig)
188#define GIC_TRIG_LEVEL 0
189#define GIC_TRIG_EDGE 1
190
191/* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */
192GIC_ACCESSOR_RW_INTR_BIT(0x200, dual)
193#define GIC_DUAL_SINGLE 0 /* when edge-triggered */
194#define GIC_DUAL_DUAL 1 /* when edge-triggered */
195
196/* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */
197GIC_ACCESSOR_RW(32, 0x280, wedge)
198#define GIC_WEDGE_RW BIT(31)
199#define GIC_WEDGE_INTR GENMASK(7, 0)
200
201/* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */
202GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask)
203
204/* GIC_SH_SMASK_* - Set shared interrupt mask bits */
205GIC_ACCESSOR_RW_INTR_BIT(0x380, smask)
206
207/* GIC_SH_MASK_* - Read the current shared interrupt mask */
208GIC_ACCESSOR_RO_INTR_BIT(0x400, mask)
209
210/* GIC_SH_PEND_* - Read currently pending shared interrupts */
211GIC_ACCESSOR_RO_INTR_BIT(0x480, pend)
212
213/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */
214GIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin)
215#define GIC_MAP_PIN_MAP_TO_PIN BIT(31)
216#define GIC_MAP_PIN_MAP_TO_NMI BIT(30)
217#define GIC_MAP_PIN_MAP GENMASK(5, 0)
218
219/* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */
220GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp)
221
222/* GIC_Vx_CTL - VP-level interrupt control */
223GIC_VX_ACCESSOR_RW(32, 0x000, ctl)
224#define GIC_VX_CTL_FDC_ROUTABLE BIT(4)
225#define GIC_VX_CTL_SWINT_ROUTABLE BIT(3)
226#define GIC_VX_CTL_PERFCNT_ROUTABLE BIT(2)
227#define GIC_VX_CTL_TIMER_ROUTABLE BIT(1)
228#define GIC_VX_CTL_EIC BIT(0)
229
230/* GIC_Vx_PEND - Read currently pending local interrupts */
231GIC_VX_ACCESSOR_RO(32, 0x004, pend)
232
233/* GIC_Vx_MASK - Read the current local interrupt mask */
234GIC_VX_ACCESSOR_RO(32, 0x008, mask)
235
236/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */
237GIC_VX_ACCESSOR_RW(32, 0x00c, rmask)
238
239/* GIC_Vx_SMASK - Set local interrupt mask bits */
240GIC_VX_ACCESSOR_RW(32, 0x010, smask)
241
242/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */
243GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map)
244
245/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */
246GIC_VX_ACCESSOR_RW(32, 0x040, wd_map)
247
248/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */
249GIC_VX_ACCESSOR_RW(32, 0x044, compare_map)
250
251/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */
252GIC_VX_ACCESSOR_RW(32, 0x048, timer_map)
253
254/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */
255GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map)
256
257/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */
258GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map)
259
260/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */
261GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map)
262
263/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */
264GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map)
265
266/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */
267GIC_VX_ACCESSOR_RW(32, 0x080, other)
268#define GIC_VX_OTHER_VPNUM GENMASK(5, 0)
269
270/* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */
271GIC_VX_ACCESSOR_RO(32, 0x088, ident)
272#define GIC_VX_IDENT_VPNUM GENMASK(5, 0)
273
274/* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */
275GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
276
277/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
278GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
279
280/**
281 * enum mips_gic_local_interrupt - GIC local interrupts
282 * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt
283 * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt
284 * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt
285 * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt
286 * @GIC_LOCAL_INT_SWINT0: Software interrupt 0
287 * @GIC_LOCAL_INT_SWINT1: Software interrupt 1
288 * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt
289 * @GIC_NUM_LOCAL_INTRS: The number of local interrupts
290 *
291 * Enumerates interrupts provided by the GIC that are local to a VP.
292 */
293enum mips_gic_local_interrupt {
294 GIC_LOCAL_INT_WD,
295 GIC_LOCAL_INT_COMPARE,
296 GIC_LOCAL_INT_TIMER,
297 GIC_LOCAL_INT_PERFCTR,
298 GIC_LOCAL_INT_SWINT0,
299 GIC_LOCAL_INT_SWINT1,
300 GIC_LOCAL_INT_FDC,
301 GIC_NUM_LOCAL_INTRS
302};
303
304/**
305 * mips_gic_present() - Determine whether a GIC is present
306 *
307 * Determines whether a MIPS Global Interrupt Controller (GIC) is present in
308 * the system that the kernel is running on.
309 *
310 * Return true if a GIC is present, else false.
311 */
312static inline bool mips_gic_present(void)
313{
314 return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
315}
316
317/**
318 * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq
319 *
320 * Determine the virq number to use for the coprocessor 0 count/compare
321 * interrupt, which may be routed via the GIC.
322 *
323 * Returns the virq number or a negative error number.
324 */
325extern int gic_get_c0_compare_int(void);
326
327/**
328 * gic_get_c0_perfcount_int() - Return performance counter interrupt virq
329 *
330 * Determine the virq number to use for CPU performance counter interrupts,
331 * which may be routed via the GIC.
332 *
333 * Returns the virq number or a negative error number.
334 */
335extern int gic_get_c0_perfcount_int(void);
336
337/**
338 * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq
339 *
340 * Determine the virq number to use for fast debug channel (FDC) interrupts,
341 * which may be routed via the GIC.
342 *
343 * Returns the virq number or a negative error number.
344 */
345extern int gic_get_c0_fdc_int(void);
346
347#endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index dbb0eceda2c6..e4ed1bc9a734 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -48,6 +48,7 @@
48#define CP0_ENTRYLO0 $2 48#define CP0_ENTRYLO0 $2
49#define CP0_ENTRYLO1 $3 49#define CP0_ENTRYLO1 $3
50#define CP0_CONF $3 50#define CP0_CONF $3
51#define CP0_GLOBALNUMBER $3, 1
51#define CP0_CONTEXT $4 52#define CP0_CONTEXT $4
52#define CP0_PAGEMASK $5 53#define CP0_PAGEMASK $5
53#define CP0_SEGCTL0 $5, 2 54#define CP0_SEGCTL0 $5, 2
@@ -148,6 +149,16 @@
148#define MIPS_ENTRYLO_RI (_ULCAST_(1) << (BITS_PER_LONG - 1)) 149#define MIPS_ENTRYLO_RI (_ULCAST_(1) << (BITS_PER_LONG - 1))
149 150
150/* 151/*
152 * MIPSr6+ GlobalNumber register definitions
153 */
154#define MIPS_GLOBALNUMBER_VP_SHF 0
155#define MIPS_GLOBALNUMBER_VP (_ULCAST_(0xff) << MIPS_GLOBALNUMBER_VP_SHF)
156#define MIPS_GLOBALNUMBER_CORE_SHF 8
157#define MIPS_GLOBALNUMBER_CORE (_ULCAST_(0xff) << MIPS_GLOBALNUMBER_CORE_SHF)
158#define MIPS_GLOBALNUMBER_CLUSTER_SHF 16
159#define MIPS_GLOBALNUMBER_CLUSTER (_ULCAST_(0xf) << MIPS_GLOBALNUMBER_CLUSTER_SHF)
160
161/*
151 * Values for PageMask register 162 * Values for PageMask register
152 */ 163 */
153#ifdef CONFIG_CPU_VR41XX 164#ifdef CONFIG_CPU_VR41XX
@@ -1446,6 +1457,8 @@ do { \
1446#define read_c0_conf() __read_32bit_c0_register($3, 0) 1457#define read_c0_conf() __read_32bit_c0_register($3, 0)
1447#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) 1458#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val)
1448 1459
1460#define read_c0_globalnumber() __read_32bit_c0_register($3, 1)
1461
1449#define read_c0_context() __read_ulong_c0_register($4, 0) 1462#define read_c0_context() __read_ulong_c0_register($4, 0)
1450#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) 1463#define write_c0_context(val) __write_ulong_c0_register($4, 0, val)
1451 1464
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index e51add184717..06552a965cf4 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -114,8 +114,6 @@ search_module_dbetables(unsigned long addr)
114#define MODULE_PROC_FAMILY "R5432 " 114#define MODULE_PROC_FAMILY "R5432 "
115#elif defined CONFIG_CPU_R5500 115#elif defined CONFIG_CPU_R5500
116#define MODULE_PROC_FAMILY "R5500 " 116#define MODULE_PROC_FAMILY "R5500 "
117#elif defined CONFIG_CPU_R6000
118#define MODULE_PROC_FAMILY "R6000 "
119#elif defined CONFIG_CPU_NEVADA 117#elif defined CONFIG_CPU_NEVADA
120#define MODULE_PROC_FAMILY "NEVADA " 118#define MODULE_PROC_FAMILY "NEVADA "
121#elif defined CONFIG_CPU_R8000 119#elif defined CONFIG_CPU_R8000
diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h
index e0717d10e650..a6e6cbebe046 100644
--- a/arch/mips/include/asm/netlogic/common.h
+++ b/arch/mips/include/asm/netlogic/common.h
@@ -84,7 +84,7 @@ nlm_set_nmi_handler(void *handler)
84 */ 84 */
85void nlm_init_boot_cpu(void); 85void nlm_init_boot_cpu(void);
86unsigned int nlm_get_cpu_frequency(void); 86unsigned int nlm_get_cpu_frequency(void);
87extern struct plat_smp_ops nlm_smp_ops; 87extern const struct plat_smp_ops nlm_smp_ops;
88extern char nlm_reset_entry[], nlm_reset_entry_end[]; 88extern char nlm_reset_entry[], nlm_reset_entry_end[];
89 89
90/* SWIOTLB */ 90/* SWIOTLB */
diff --git a/arch/mips/include/asm/octeon/cvmx-boot-vector.h b/arch/mips/include/asm/octeon/cvmx-boot-vector.h
new file mode 100644
index 000000000000..8db08241d53c
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-boot-vector.h
@@ -0,0 +1,53 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003-2017 Cavium, Inc.
7 */
8
9#ifndef __CVMX_BOOT_VECTOR_H__
10#define __CVMX_BOOT_VECTOR_H__
11
12#include <asm/octeon/octeon.h>
13
14/*
15 * The boot vector table is made up of an array of 1024 elements of
16 * struct cvmx_boot_vector_element. There is one entry for each
17 * possible MIPS CPUNum, indexed by the CPUNum.
18 *
19 * Once cvmx_boot_vector_get() returns a non-NULL value (indicating
20 * success), NMI to a core will cause execution to transfer to the
21 * target_ptr location for that core's entry in the vector table.
22 *
23 * The struct cvmx_boot_vector_element fields app0, app1, and app2 can
24 * be used by the application that has set the target_ptr in any
25 * application specific manner, they are not touched by the vectoring
26 * code.
27 *
28 * The boot vector code clobbers the CP0_DESAVE register, and on
29 * OCTEON II and later CPUs also clobbers CP0_KScratch2. All GP
30 * registers are preserved, except on pre-OCTEON II CPUs, where k1 is
31 * clobbered.
32 *
33 */
34
35
36/*
37 * Applications install the boot bus code in cvmx-boot-vector.c, which
38 * uses this magic:
39 */
40#define OCTEON_BOOT_MOVEABLE_MAGIC1 0xdb00110ad358eacdull
41
42struct cvmx_boot_vector_element {
43 /* kseg0 or xkphys address of target code. */
44 uint64_t target_ptr;
45 /* Three application specific arguments. */
46 uint64_t app0;
47 uint64_t app1;
48 uint64_t app2;
49};
50
51struct cvmx_boot_vector_element *cvmx_boot_vector_get(void);
52
53#endif /* __CVMX_BOOT_VECTOR_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h
index 374562507d0b..72d2e403a6e4 100644
--- a/arch/mips/include/asm/octeon/cvmx-bootmem.h
+++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h
@@ -255,6 +255,34 @@ extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
255 uint64_t max_addr, uint64_t align, 255 uint64_t max_addr, uint64_t align,
256 char *name); 256 char *name);
257 257
258/**
259 * Allocate if needed a block of memory from a specific range of the
260 * free list that was passed to the application by the bootloader, and
261 * assign it a name in the global named block table. (part of the
262 * cvmx_bootmem_descriptor_t structure) Named blocks can later be
263 * freed. If the requested name block is already allocated, return
264 * the pointer to block of memory. If request cannot be satisfied
265 * within the address range specified, NULL is returned
266 *
267 * @param size Size in bytes of block to allocate
268 * @param min_addr minimum address of range
269 * @param max_addr maximum address of range
270 * @param align Alignment of memory to be allocated. (must be a power of 2)
271 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
272 * @param init Initialization function
273 *
274 * The initialization function is optional, if omitted the named block
275 * is initialized to all zeros when it is created, i.e. once.
276 *
277 * @return pointer to block of memory, NULL on error
278 */
279void *cvmx_bootmem_alloc_named_range_once(uint64_t size,
280 uint64_t min_addr,
281 uint64_t max_addr,
282 uint64_t align,
283 char *name,
284 void (*init) (void *));
285
258extern int cvmx_bootmem_free_named(char *name); 286extern int cvmx_bootmem_free_named(char *name);
259 287
260/** 288/**
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
index 0dd0e40c96d4..6e61792d9248 100644
--- a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
@@ -128,6 +128,7 @@ static inline uint64_t CVMX_CIU_PP_POKEX(unsigned long offset)
128 case OCTEON_CN52XX & OCTEON_FAMILY_MASK: 128 case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
129 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: 129 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
130 case OCTEON_CN61XX & OCTEON_FAMILY_MASK: 130 case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
131 case OCTEON_CN70XX & OCTEON_FAMILY_MASK:
131 return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; 132 return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
132 case OCTEON_CN31XX & OCTEON_FAMILY_MASK: 133 case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
133 case OCTEON_CN50XX & OCTEON_FAMILY_MASK: 134 case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
@@ -143,6 +144,10 @@ static inline uint64_t CVMX_CIU_PP_POKEX(unsigned long offset)
143 return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; 144 return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
144 case OCTEON_CN68XX & OCTEON_FAMILY_MASK: 145 case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
145 return CVMX_ADD_IO_SEG(0x0001070100100200ull) + (offset) * 8; 146 return CVMX_ADD_IO_SEG(0x0001070100100200ull) + (offset) * 8;
147 case OCTEON_CNF75XX & OCTEON_FAMILY_MASK:
148 case OCTEON_CN73XX & OCTEON_FAMILY_MASK:
149 case OCTEON_CN78XX & OCTEON_FAMILY_MASK:
150 return CVMX_ADD_IO_SEG(0x0001010000030000ull) + (offset) * 8;
146 } 151 }
147 return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; 152 return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
148} 153}
@@ -180,6 +185,7 @@ static inline uint64_t CVMX_CIU_WDOGX(unsigned long offset)
180 case OCTEON_CN52XX & OCTEON_FAMILY_MASK: 185 case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
181 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: 186 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
182 case OCTEON_CN61XX & OCTEON_FAMILY_MASK: 187 case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
188 case OCTEON_CN70XX & OCTEON_FAMILY_MASK:
183 return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; 189 return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
184 case OCTEON_CN31XX & OCTEON_FAMILY_MASK: 190 case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
185 case OCTEON_CN50XX & OCTEON_FAMILY_MASK: 191 case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
@@ -195,6 +201,10 @@ static inline uint64_t CVMX_CIU_WDOGX(unsigned long offset)
195 return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; 201 return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
196 case OCTEON_CN68XX & OCTEON_FAMILY_MASK: 202 case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
197 return CVMX_ADD_IO_SEG(0x0001070100100000ull) + (offset) * 8; 203 return CVMX_ADD_IO_SEG(0x0001070100100000ull) + (offset) * 8;
204 case OCTEON_CNF75XX & OCTEON_FAMILY_MASK:
205 case OCTEON_CN73XX & OCTEON_FAMILY_MASK:
206 case OCTEON_CN78XX & OCTEON_FAMILY_MASK:
207 return CVMX_ADD_IO_SEG(0x0001010000020000ull) + (offset) * 8;
198 } 208 }
199 return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; 209 return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
200} 210}
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index e638735cc3ac..205ab2ce10f8 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -357,6 +357,34 @@ static inline unsigned int cvmx_get_local_core_num(void)
357 return cvmx_get_core_num() & ((1 << CVMX_NODE_NO_SHIFT) - 1); 357 return cvmx_get_core_num() & ((1 << CVMX_NODE_NO_SHIFT) - 1);
358} 358}
359 359
360#define CVMX_NODE_BITS (2) /* Number of bits to define a node */
361#define CVMX_MAX_NODES (1 << CVMX_NODE_BITS)
362#define CVMX_NODE_IO_SHIFT (36)
363#define CVMX_NODE_MEM_SHIFT (40)
364#define CVMX_NODE_IO_MASK ((uint64_t)CVMX_NODE_MASK << CVMX_NODE_IO_SHIFT)
365
366static inline void cvmx_write_csr_node(uint64_t node, uint64_t csr_addr,
367 uint64_t val)
368{
369 uint64_t composite_csr_addr, node_addr;
370
371 node_addr = (node & CVMX_NODE_MASK) << CVMX_NODE_IO_SHIFT;
372 composite_csr_addr = (csr_addr & ~CVMX_NODE_IO_MASK) | node_addr;
373
374 cvmx_write64_uint64(composite_csr_addr, val);
375 if (((csr_addr >> 40) & 0x7ffff) == (0x118))
376 cvmx_read64_uint64(CVMX_MIO_BOOT_BIST_STAT | node_addr);
377}
378
379static inline uint64_t cvmx_read_csr_node(uint64_t node, uint64_t csr_addr)
380{
381 uint64_t node_addr;
382
383 node_addr = (csr_addr & ~CVMX_NODE_IO_MASK) |
384 (node & CVMX_NODE_MASK) << CVMX_NODE_IO_SHIFT;
385 return cvmx_read_csr(node_addr);
386}
387
360/** 388/**
361 * Returns the number of bits set in the provided value. 389 * Returns the number of bits set in the provided value.
362 * Simple wrapper for POP instruction. 390 * Simple wrapper for POP instruction.
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index 07c0516ef4d5..c99c4b6a79f4 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -362,4 +362,6 @@ extern void octeon_fixup_irqs(void);
362 362
363extern struct semaphore octeon_bootbus_sem; 363extern struct semaphore octeon_bootbus_sem;
364 364
365struct irq_domain *octeon_irq_get_block_domain(int node, uint8_t block);
366
365#endif /* __ASM_OCTEON_OCTEON_H */ 367#endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
index db7c322f057f..53b2cb8e5966 100644
--- a/arch/mips/include/asm/smp-ops.h
+++ b/arch/mips/include/asm/smp-ops.h
@@ -13,7 +13,7 @@
13 13
14#include <linux/errno.h> 14#include <linux/errno.h>
15 15
16#include <asm/mips-cm.h> 16#include <asm/mips-cps.h>
17 17
18#ifdef CONFIG_SMP 18#ifdef CONFIG_SMP
19 19
@@ -26,7 +26,7 @@ struct plat_smp_ops {
26 void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action); 26 void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action);
27 void (*init_secondary)(void); 27 void (*init_secondary)(void);
28 void (*smp_finish)(void); 28 void (*smp_finish)(void);
29 void (*boot_secondary)(int cpu, struct task_struct *idle); 29 int (*boot_secondary)(int cpu, struct task_struct *idle);
30 void (*smp_setup)(void); 30 void (*smp_setup)(void);
31 void (*prepare_cpus)(unsigned int max_cpus); 31 void (*prepare_cpus)(unsigned int max_cpus);
32#ifdef CONFIG_HOTPLUG_CPU 32#ifdef CONFIG_HOTPLUG_CPU
@@ -35,11 +35,11 @@ struct plat_smp_ops {
35#endif 35#endif
36}; 36};
37 37
38extern void register_smp_ops(struct plat_smp_ops *ops); 38extern void register_smp_ops(const struct plat_smp_ops *ops);
39 39
40static inline void plat_smp_setup(void) 40static inline void plat_smp_setup(void)
41{ 41{
42 extern struct plat_smp_ops *mp_ops; /* private */ 42 extern const struct plat_smp_ops *mp_ops; /* private */
43 43
44 mp_ops->smp_setup(); 44 mp_ops->smp_setup();
45} 45}
@@ -57,7 +57,7 @@ static inline void plat_smp_setup(void)
57 /* UP, nothing to do ... */ 57 /* UP, nothing to do ... */
58} 58}
59 59
60static inline void register_smp_ops(struct plat_smp_ops *ops) 60static inline void register_smp_ops(const struct plat_smp_ops *ops)
61{ 61{
62} 62}
63 63
@@ -66,7 +66,7 @@ static inline void register_smp_ops(struct plat_smp_ops *ops)
66static inline int register_up_smp_ops(void) 66static inline int register_up_smp_ops(void)
67{ 67{
68#ifdef CONFIG_SMP_UP 68#ifdef CONFIG_SMP_UP
69 extern struct plat_smp_ops up_smp_ops; 69 extern const struct plat_smp_ops up_smp_ops;
70 70
71 register_smp_ops(&up_smp_ops); 71 register_smp_ops(&up_smp_ops);
72 72
@@ -79,7 +79,7 @@ static inline int register_up_smp_ops(void)
79static inline int register_cmp_smp_ops(void) 79static inline int register_cmp_smp_ops(void)
80{ 80{
81#ifdef CONFIG_MIPS_CMP 81#ifdef CONFIG_MIPS_CMP
82 extern struct plat_smp_ops cmp_smp_ops; 82 extern const struct plat_smp_ops cmp_smp_ops;
83 83
84 if (!mips_cm_present()) 84 if (!mips_cm_present())
85 return -ENODEV; 85 return -ENODEV;
@@ -95,7 +95,7 @@ static inline int register_cmp_smp_ops(void)
95static inline int register_vsmp_smp_ops(void) 95static inline int register_vsmp_smp_ops(void)
96{ 96{
97#ifdef CONFIG_MIPS_MT_SMP 97#ifdef CONFIG_MIPS_MT_SMP
98 extern struct plat_smp_ops vsmp_smp_ops; 98 extern const struct plat_smp_ops vsmp_smp_ops;
99 99
100 register_smp_ops(&vsmp_smp_ops); 100 register_smp_ops(&vsmp_smp_ops);
101 101
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
index bab3d41e5987..9e494f8d9c03 100644
--- a/arch/mips/include/asm/smp.h
+++ b/arch/mips/include/asm/smp.h
@@ -58,7 +58,7 @@ extern void calculate_cpu_foreign_map(void);
58 */ 58 */
59static inline void smp_send_reschedule(int cpu) 59static inline void smp_send_reschedule(int cpu)
60{ 60{
61 extern struct plat_smp_ops *mp_ops; /* private */ 61 extern const struct plat_smp_ops *mp_ops; /* private */
62 62
63 mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF); 63 mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF);
64} 64}
@@ -66,14 +66,14 @@ static inline void smp_send_reschedule(int cpu)
66#ifdef CONFIG_HOTPLUG_CPU 66#ifdef CONFIG_HOTPLUG_CPU
67static inline int __cpu_disable(void) 67static inline int __cpu_disable(void)
68{ 68{
69 extern struct plat_smp_ops *mp_ops; /* private */ 69 extern const struct plat_smp_ops *mp_ops; /* private */
70 70
71 return mp_ops->cpu_disable(); 71 return mp_ops->cpu_disable();
72} 72}
73 73
74static inline void __cpu_die(unsigned int cpu) 74static inline void __cpu_die(unsigned int cpu)
75{ 75{
76 extern struct plat_smp_ops *mp_ops; /* private */ 76 extern const struct plat_smp_ops *mp_ops; /* private */
77 77
78 mp_ops->cpu_die(cpu); 78 mp_ops->cpu_die(cpu);
79} 79}
@@ -97,14 +97,14 @@ int mips_smp_ipi_free(const struct cpumask *mask);
97 97
98static inline void arch_send_call_function_single_ipi(int cpu) 98static inline void arch_send_call_function_single_ipi(int cpu)
99{ 99{
100 extern struct plat_smp_ops *mp_ops; /* private */ 100 extern const struct plat_smp_ops *mp_ops; /* private */
101 101
102 mp_ops->send_ipi_mask(cpumask_of(cpu), SMP_CALL_FUNCTION); 102 mp_ops->send_ipi_mask(cpumask_of(cpu), SMP_CALL_FUNCTION);
103} 103}
104 104
105static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) 105static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
106{ 106{
107 extern struct plat_smp_ops *mp_ops; /* private */ 107 extern const struct plat_smp_ops *mp_ops; /* private */
108 108
109 mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION); 109 mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
110} 110}
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index eaa5a4d7d5e5..5d3563c55e0c 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -19,20 +19,43 @@
19#include <asm/asm-offsets.h> 19#include <asm/asm-offsets.h>
20#include <asm/thread_info.h> 20#include <asm/thread_info.h>
21 21
22/* Make the addition of cfi info a little easier. */
23 .macro cfi_rel_offset reg offset=0 docfi=0
24 .if \docfi
25 .cfi_rel_offset \reg, \offset
26 .endif
27 .endm
28
29 .macro cfi_st reg offset=0 docfi=0
30 LONG_S \reg, \offset(sp)
31 cfi_rel_offset \reg, \offset, \docfi
32 .endm
33
34 .macro cfi_restore reg offset=0 docfi=0
35 .if \docfi
36 .cfi_restore \reg
37 .endif
38 .endm
39
40 .macro cfi_ld reg offset=0 docfi=0
41 LONG_L \reg, \offset(sp)
42 cfi_restore \reg \offset \docfi
43 .endm
44
22#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 45#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
23#define STATMASK 0x3f 46#define STATMASK 0x3f
24#else 47#else
25#define STATMASK 0x1f 48#define STATMASK 0x1f
26#endif 49#endif
27 50
28 .macro SAVE_AT 51 .macro SAVE_AT docfi=0
29 .set push 52 .set push
30 .set noat 53 .set noat
31 LONG_S $1, PT_R1(sp) 54 cfi_st $1, PT_R1, \docfi
32 .set pop 55 .set pop
33 .endm 56 .endm
34 57
35 .macro SAVE_TEMP 58 .macro SAVE_TEMP docfi=0
36#ifdef CONFIG_CPU_HAS_SMARTMIPS 59#ifdef CONFIG_CPU_HAS_SMARTMIPS
37 mflhxu v1 60 mflhxu v1
38 LONG_S v1, PT_LO(sp) 61 LONG_S v1, PT_LO(sp)
@@ -44,20 +67,20 @@
44 mfhi v1 67 mfhi v1
45#endif 68#endif
46#ifdef CONFIG_32BIT 69#ifdef CONFIG_32BIT
47 LONG_S $8, PT_R8(sp) 70 cfi_st $8, PT_R8, \docfi
48 LONG_S $9, PT_R9(sp) 71 cfi_st $9, PT_R9, \docfi
49#endif 72#endif
50 LONG_S $10, PT_R10(sp) 73 cfi_st $10, PT_R10, \docfi
51 LONG_S $11, PT_R11(sp) 74 cfi_st $11, PT_R11, \docfi
52 LONG_S $12, PT_R12(sp) 75 cfi_st $12, PT_R12, \docfi
53#if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6) 76#if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6)
54 LONG_S v1, PT_HI(sp) 77 LONG_S v1, PT_HI(sp)
55 mflo v1 78 mflo v1
56#endif 79#endif
57 LONG_S $13, PT_R13(sp) 80 cfi_st $13, PT_R13, \docfi
58 LONG_S $14, PT_R14(sp) 81 cfi_st $14, PT_R14, \docfi
59 LONG_S $15, PT_R15(sp) 82 cfi_st $15, PT_R15, \docfi
60 LONG_S $24, PT_R24(sp) 83 cfi_st $24, PT_R24, \docfi
61#if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6) 84#if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6)
62 LONG_S v1, PT_LO(sp) 85 LONG_S v1, PT_LO(sp)
63#endif 86#endif
@@ -71,20 +94,28 @@
71#endif 94#endif
72 .endm 95 .endm
73 96
74 .macro SAVE_STATIC 97 .macro SAVE_STATIC docfi=0
75 LONG_S $16, PT_R16(sp) 98 cfi_st $16, PT_R16, \docfi
76 LONG_S $17, PT_R17(sp) 99 cfi_st $17, PT_R17, \docfi
77 LONG_S $18, PT_R18(sp) 100 cfi_st $18, PT_R18, \docfi
78 LONG_S $19, PT_R19(sp) 101 cfi_st $19, PT_R19, \docfi
79 LONG_S $20, PT_R20(sp) 102 cfi_st $20, PT_R20, \docfi
80 LONG_S $21, PT_R21(sp) 103 cfi_st $21, PT_R21, \docfi
81 LONG_S $22, PT_R22(sp) 104 cfi_st $22, PT_R22, \docfi
82 LONG_S $23, PT_R23(sp) 105 cfi_st $23, PT_R23, \docfi
83 LONG_S $30, PT_R30(sp) 106 cfi_st $30, PT_R30, \docfi
84 .endm 107 .endm
85 108
109/*
110 * get_saved_sp returns the SP for the current CPU by looking in the
111 * kernelsp array for it. If tosp is set, it stores the current sp in
112 * k0 and loads the new value in sp. If not, it clobbers k0 and
113 * stores the new value in k1, leaving sp unaffected.
114 */
86#ifdef CONFIG_SMP 115#ifdef CONFIG_SMP
87 .macro get_saved_sp /* SMP variation */ 116
117 /* SMP variation */
118 .macro get_saved_sp docfi=0 tosp=0
88 ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG 119 ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
89#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) 120#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
90 lui k1, %hi(kernelsp) 121 lui k1, %hi(kernelsp)
@@ -97,7 +128,15 @@
97#endif 128#endif
98 LONG_SRL k0, SMP_CPUID_PTRSHIFT 129 LONG_SRL k0, SMP_CPUID_PTRSHIFT
99 LONG_ADDU k1, k0 130 LONG_ADDU k1, k0
131 .if \tosp
132 move k0, sp
133 .if \docfi
134 .cfi_register sp, k0
135 .endif
136 LONG_L sp, %lo(kernelsp)(k1)
137 .else
100 LONG_L k1, %lo(kernelsp)(k1) 138 LONG_L k1, %lo(kernelsp)(k1)
139 .endif
101 .endm 140 .endm
102 141
103 .macro set_saved_sp stackp temp temp2 142 .macro set_saved_sp stackp temp temp2
@@ -106,7 +145,8 @@
106 LONG_S \stackp, kernelsp(\temp) 145 LONG_S \stackp, kernelsp(\temp)
107 .endm 146 .endm
108#else /* !CONFIG_SMP */ 147#else /* !CONFIG_SMP */
109 .macro get_saved_sp /* Uniprocessor variation */ 148 /* Uniprocessor variation */
149 .macro get_saved_sp docfi=0 tosp=0
110#ifdef CONFIG_CPU_JUMP_WORKAROUNDS 150#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
111 /* 151 /*
112 * Clear BTB (branch target buffer), forbid RAS (return address 152 * Clear BTB (branch target buffer), forbid RAS (return address
@@ -135,7 +175,15 @@
135 daddiu k1, %hi(kernelsp) 175 daddiu k1, %hi(kernelsp)
136 dsll k1, k1, 16 176 dsll k1, k1, 16
137#endif 177#endif
178 .if \tosp
179 move k0, sp
180 .if \docfi
181 .cfi_register sp, k0
182 .endif
183 LONG_L sp, %lo(kernelsp)(k1)
184 .else
138 LONG_L k1, %lo(kernelsp)(k1) 185 LONG_L k1, %lo(kernelsp)(k1)
186 .endif
139 .endm 187 .endm
140 188
141 .macro set_saved_sp stackp temp temp2 189 .macro set_saved_sp stackp temp temp2
@@ -143,7 +191,7 @@
143 .endm 191 .endm
144#endif 192#endif
145 193
146 .macro SAVE_SOME 194 .macro SAVE_SOME docfi=0
147 .set push 195 .set push
148 .set noat 196 .set noat
149 .set reorder 197 .set reorder
@@ -151,7 +199,6 @@
151 sll k0, 3 /* extract cu0 bit */ 199 sll k0, 3 /* extract cu0 bit */
152 .set noreorder 200 .set noreorder
153 bltz k0, 8f 201 bltz k0, 8f
154 move k1, sp
155#ifdef CONFIG_EVA 202#ifdef CONFIG_EVA
156 /* 203 /*
157 * Flush interAptiv's Return Prediction Stack (RPS) by writing 204 * Flush interAptiv's Return Prediction Stack (RPS) by writing
@@ -178,20 +225,26 @@
178 MTC0 k0, CP0_ENTRYHI 225 MTC0 k0, CP0_ENTRYHI
179#endif 226#endif
180 .set reorder 227 .set reorder
228 move k0, sp
229 .if \docfi
230 .cfi_register sp, k0
231 .endif
181 /* Called from user mode, new stack. */ 232 /* Called from user mode, new stack. */
182 get_saved_sp 233 get_saved_sp docfi=\docfi tosp=1
183#ifndef CONFIG_CPU_DADDI_WORKAROUNDS 2348:
1848: move k0, sp 235#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
185 PTR_SUBU sp, k1, PT_SIZE 236 .set at=k1
186#else 237#endif
187 .set at=k0 238 PTR_SUBU sp, PT_SIZE
1888: PTR_SUBU k1, PT_SIZE 239#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
189 .set noat 240 .set noat
190 move k0, sp
191 move sp, k1
192#endif 241#endif
193 LONG_S k0, PT_R29(sp) 242 .if \docfi
194 LONG_S $3, PT_R3(sp) 243 .cfi_def_cfa sp,0
244 .endif
245 cfi_st k0, PT_R29, \docfi
246 cfi_rel_offset sp, PT_R29, \docfi
247 cfi_st v1, PT_R3, \docfi
195 /* 248 /*
196 * You might think that you don't need to save $0, 249 * You might think that you don't need to save $0,
197 * but the FPU emulator and gdb remote debug stub 250 * but the FPU emulator and gdb remote debug stub
@@ -199,23 +252,26 @@
199 */ 252 */
200 LONG_S $0, PT_R0(sp) 253 LONG_S $0, PT_R0(sp)
201 mfc0 v1, CP0_STATUS 254 mfc0 v1, CP0_STATUS
202 LONG_S $2, PT_R2(sp) 255 cfi_st v0, PT_R2, \docfi
203 LONG_S v1, PT_STATUS(sp) 256 LONG_S v1, PT_STATUS(sp)
204 LONG_S $4, PT_R4(sp) 257 cfi_st $4, PT_R4, \docfi
205 mfc0 v1, CP0_CAUSE 258 mfc0 v1, CP0_CAUSE
206 LONG_S $5, PT_R5(sp) 259 cfi_st $5, PT_R5, \docfi
207 LONG_S v1, PT_CAUSE(sp) 260 LONG_S v1, PT_CAUSE(sp)
208 LONG_S $6, PT_R6(sp) 261 cfi_st $6, PT_R6, \docfi
209 MFC0 v1, CP0_EPC 262 cfi_st ra, PT_R31, \docfi
210 LONG_S $7, PT_R7(sp) 263 MFC0 ra, CP0_EPC
264 cfi_st $7, PT_R7, \docfi
211#ifdef CONFIG_64BIT 265#ifdef CONFIG_64BIT
212 LONG_S $8, PT_R8(sp) 266 cfi_st $8, PT_R8, \docfi
213 LONG_S $9, PT_R9(sp) 267 cfi_st $9, PT_R9, \docfi
214#endif 268#endif
215 LONG_S v1, PT_EPC(sp) 269 LONG_S ra, PT_EPC(sp)
216 LONG_S $25, PT_R25(sp) 270 .if \docfi
217 LONG_S $28, PT_R28(sp) 271 .cfi_rel_offset ra, PT_EPC
218 LONG_S $31, PT_R31(sp) 272 .endif
273 cfi_st $25, PT_R25, \docfi
274 cfi_st $28, PT_R28, \docfi
219 275
220 /* Set thread_info if we're coming from user mode */ 276 /* Set thread_info if we're coming from user mode */
221 mfc0 k0, CP0_STATUS 277 mfc0 k0, CP0_STATUS
@@ -232,21 +288,21 @@
232 .set pop 288 .set pop
233 .endm 289 .endm
234 290
235 .macro SAVE_ALL 291 .macro SAVE_ALL docfi=0
236 SAVE_SOME 292 SAVE_SOME \docfi
237 SAVE_AT 293 SAVE_AT \docfi
238 SAVE_TEMP 294 SAVE_TEMP \docfi
239 SAVE_STATIC 295 SAVE_STATIC \docfi
240 .endm 296 .endm
241 297
242 .macro RESTORE_AT 298 .macro RESTORE_AT docfi=0
243 .set push 299 .set push
244 .set noat 300 .set noat
245 LONG_L $1, PT_R1(sp) 301 cfi_ld $1, PT_R1, \docfi
246 .set pop 302 .set pop
247 .endm 303 .endm
248 304
249 .macro RESTORE_TEMP 305 .macro RESTORE_TEMP docfi=0
250#ifdef CONFIG_CPU_CAVIUM_OCTEON 306#ifdef CONFIG_CPU_CAVIUM_OCTEON
251 /* Restore the Octeon multiplier state */ 307 /* Restore the Octeon multiplier state */
252 jal octeon_mult_restore 308 jal octeon_mult_restore
@@ -265,33 +321,37 @@
265 mthi $24 321 mthi $24
266#endif 322#endif
267#ifdef CONFIG_32BIT 323#ifdef CONFIG_32BIT
268 LONG_L $8, PT_R8(sp) 324 cfi_ld $8, PT_R8, \docfi
269 LONG_L $9, PT_R9(sp) 325 cfi_ld $9, PT_R9, \docfi
270#endif 326#endif
271 LONG_L $10, PT_R10(sp) 327 cfi_ld $10, PT_R10, \docfi
272 LONG_L $11, PT_R11(sp) 328 cfi_ld $11, PT_R11, \docfi
273 LONG_L $12, PT_R12(sp) 329 cfi_ld $12, PT_R12, \docfi
274 LONG_L $13, PT_R13(sp) 330 cfi_ld $13, PT_R13, \docfi
275 LONG_L $14, PT_R14(sp) 331 cfi_ld $14, PT_R14, \docfi
276 LONG_L $15, PT_R15(sp) 332 cfi_ld $15, PT_R15, \docfi
277 LONG_L $24, PT_R24(sp) 333 cfi_ld $24, PT_R24, \docfi
278 .endm 334 .endm
279 335
280 .macro RESTORE_STATIC 336 .macro RESTORE_STATIC docfi=0
281 LONG_L $16, PT_R16(sp) 337 cfi_ld $16, PT_R16, \docfi
282 LONG_L $17, PT_R17(sp) 338 cfi_ld $17, PT_R17, \docfi
283 LONG_L $18, PT_R18(sp) 339 cfi_ld $18, PT_R18, \docfi
284 LONG_L $19, PT_R19(sp) 340 cfi_ld $19, PT_R19, \docfi
285 LONG_L $20, PT_R20(sp) 341 cfi_ld $20, PT_R20, \docfi
286 LONG_L $21, PT_R21(sp) 342 cfi_ld $21, PT_R21, \docfi
287 LONG_L $22, PT_R22(sp) 343 cfi_ld $22, PT_R22, \docfi
288 LONG_L $23, PT_R23(sp) 344 cfi_ld $23, PT_R23, \docfi
289 LONG_L $30, PT_R30(sp) 345 cfi_ld $30, PT_R30, \docfi
346 .endm
347
348 .macro RESTORE_SP docfi=0
349 cfi_ld sp, PT_R29, \docfi
290 .endm 350 .endm
291 351
292#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 352#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
293 353
294 .macro RESTORE_SOME 354 .macro RESTORE_SOME docfi=0
295 .set push 355 .set push
296 .set reorder 356 .set reorder
297 .set noat 357 .set noat
@@ -306,30 +366,30 @@
306 and v0, v1 366 and v0, v1
307 or v0, a0 367 or v0, a0
308 mtc0 v0, CP0_STATUS 368 mtc0 v0, CP0_STATUS
309 LONG_L $31, PT_R31(sp) 369 cfi_ld $31, PT_R31, \docfi
310 LONG_L $28, PT_R28(sp) 370 cfi_ld $28, PT_R28, \docfi
311 LONG_L $25, PT_R25(sp) 371 cfi_ld $25, PT_R25, \docfi
312 LONG_L $7, PT_R7(sp) 372 cfi_ld $7, PT_R7, \docfi
313 LONG_L $6, PT_R6(sp) 373 cfi_ld $6, PT_R6, \docfi
314 LONG_L $5, PT_R5(sp) 374 cfi_ld $5, PT_R5, \docfi
315 LONG_L $4, PT_R4(sp) 375 cfi_ld $4, PT_R4, \docfi
316 LONG_L $3, PT_R3(sp) 376 cfi_ld $3, PT_R3, \docfi
317 LONG_L $2, PT_R2(sp) 377 cfi_ld $2, PT_R2, \docfi
318 .set pop 378 .set pop
319 .endm 379 .endm
320 380
321 .macro RESTORE_SP_AND_RET 381 .macro RESTORE_SP_AND_RET docfi=0
322 .set push 382 .set push
323 .set noreorder 383 .set noreorder
324 LONG_L k0, PT_EPC(sp) 384 LONG_L k0, PT_EPC(sp)
325 LONG_L sp, PT_R29(sp) 385 RESTORE_SP \docfi
326 jr k0 386 jr k0
327 rfe 387 rfe
328 .set pop 388 .set pop
329 .endm 389 .endm
330 390
331#else 391#else
332 .macro RESTORE_SOME 392 .macro RESTORE_SOME docfi=0
333 .set push 393 .set push
334 .set reorder 394 .set reorder
335 .set noat 395 .set noat
@@ -346,24 +406,24 @@
346 mtc0 v0, CP0_STATUS 406 mtc0 v0, CP0_STATUS
347 LONG_L v1, PT_EPC(sp) 407 LONG_L v1, PT_EPC(sp)
348 MTC0 v1, CP0_EPC 408 MTC0 v1, CP0_EPC
349 LONG_L $31, PT_R31(sp) 409 cfi_ld $31, PT_R31, \docfi
350 LONG_L $28, PT_R28(sp) 410 cfi_ld $28, PT_R28, \docfi
351 LONG_L $25, PT_R25(sp) 411 cfi_ld $25, PT_R25, \docfi
352#ifdef CONFIG_64BIT 412#ifdef CONFIG_64BIT
353 LONG_L $8, PT_R8(sp) 413 cfi_ld $8, PT_R8, \docfi
354 LONG_L $9, PT_R9(sp) 414 cfi_ld $9, PT_R9, \docfi
355#endif 415#endif
356 LONG_L $7, PT_R7(sp) 416 cfi_ld $7, PT_R7, \docfi
357 LONG_L $6, PT_R6(sp) 417 cfi_ld $6, PT_R6, \docfi
358 LONG_L $5, PT_R5(sp) 418 cfi_ld $5, PT_R5, \docfi
359 LONG_L $4, PT_R4(sp) 419 cfi_ld $4, PT_R4, \docfi
360 LONG_L $3, PT_R3(sp) 420 cfi_ld $3, PT_R3, \docfi
361 LONG_L $2, PT_R2(sp) 421 cfi_ld $2, PT_R2, \docfi
362 .set pop 422 .set pop
363 .endm 423 .endm
364 424
365 .macro RESTORE_SP_AND_RET 425 .macro RESTORE_SP_AND_RET docfi=0
366 LONG_L sp, PT_R29(sp) 426 RESTORE_SP \docfi
367#ifdef CONFIG_CPU_MIPSR6 427#ifdef CONFIG_CPU_MIPSR6
368 eretnc 428 eretnc
369#else 429#else
@@ -375,16 +435,12 @@
375 435
376#endif 436#endif
377 437
378 .macro RESTORE_SP 438 .macro RESTORE_ALL docfi=0
379 LONG_L sp, PT_R29(sp) 439 RESTORE_TEMP \docfi
380 .endm 440 RESTORE_STATIC \docfi
381 441 RESTORE_AT \docfi
382 .macro RESTORE_ALL 442 RESTORE_SOME \docfi
383 RESTORE_TEMP 443 RESTORE_SP \docfi
384 RESTORE_STATIC
385 RESTORE_AT
386 RESTORE_SOME
387 RESTORE_SP
388 .endm 444 .endm
389 445
390/* 446/*
diff --git a/arch/mips/include/asm/stacktrace.h b/arch/mips/include/asm/stacktrace.h
index 780ee2c2a2ac..10c4e9c84448 100644
--- a/arch/mips/include/asm/stacktrace.h
+++ b/arch/mips/include/asm/stacktrace.h
@@ -2,6 +2,8 @@
2#define _ASM_STACKTRACE_H 2#define _ASM_STACKTRACE_H
3 3
4#include <asm/ptrace.h> 4#include <asm/ptrace.h>
5#include <asm/asm.h>
6#include <linux/stringify.h>
5 7
6#ifdef CONFIG_KALLSYMS 8#ifdef CONFIG_KALLSYMS
7extern int raw_show_trace; 9extern int raw_show_trace;
@@ -20,6 +22,14 @@ static inline unsigned long unwind_stack(struct task_struct *task,
20} 22}
21#endif 23#endif
22 24
25#define STR_PTR_LA __stringify(PTR_LA)
26#define STR_LONG_S __stringify(LONG_S)
27#define STR_LONG_L __stringify(LONG_L)
28#define STR_LONGSIZE __stringify(LONGSIZE)
29
30#define STORE_ONE_REG(r) \
31 STR_LONG_S " $" __stringify(r)",("STR_LONGSIZE"*"__stringify(r)")(%1)\n\t"
32
23static __always_inline void prepare_frametrace(struct pt_regs *regs) 33static __always_inline void prepare_frametrace(struct pt_regs *regs)
24{ 34{
25#ifndef CONFIG_KALLSYMS 35#ifndef CONFIG_KALLSYMS
@@ -32,21 +42,47 @@ static __always_inline void prepare_frametrace(struct pt_regs *regs)
32 __asm__ __volatile__( 42 __asm__ __volatile__(
33 ".set push\n\t" 43 ".set push\n\t"
34 ".set noat\n\t" 44 ".set noat\n\t"
35#ifdef CONFIG_64BIT 45 /* Store $1 so we can use it */
36 "1: dla $1, 1b\n\t" 46 STR_LONG_S " $1,"STR_LONGSIZE"(%1)\n\t"
37 "sd $1, %0\n\t" 47 /* Store the PC */
38 "sd $29, %1\n\t" 48 "1: " STR_PTR_LA " $1, 1b\n\t"
39 "sd $31, %2\n\t" 49 STR_LONG_S " $1,%0\n\t"
40#else 50 STORE_ONE_REG(2)
41 "1: la $1, 1b\n\t" 51 STORE_ONE_REG(3)
42 "sw $1, %0\n\t" 52 STORE_ONE_REG(4)
43 "sw $29, %1\n\t" 53 STORE_ONE_REG(5)
44 "sw $31, %2\n\t" 54 STORE_ONE_REG(6)
45#endif 55 STORE_ONE_REG(7)
56 STORE_ONE_REG(8)
57 STORE_ONE_REG(9)
58 STORE_ONE_REG(10)
59 STORE_ONE_REG(11)
60 STORE_ONE_REG(12)
61 STORE_ONE_REG(13)
62 STORE_ONE_REG(14)
63 STORE_ONE_REG(15)
64 STORE_ONE_REG(16)
65 STORE_ONE_REG(17)
66 STORE_ONE_REG(18)
67 STORE_ONE_REG(19)
68 STORE_ONE_REG(20)
69 STORE_ONE_REG(21)
70 STORE_ONE_REG(22)
71 STORE_ONE_REG(23)
72 STORE_ONE_REG(24)
73 STORE_ONE_REG(25)
74 STORE_ONE_REG(26)
75 STORE_ONE_REG(27)
76 STORE_ONE_REG(28)
77 STORE_ONE_REG(29)
78 STORE_ONE_REG(30)
79 STORE_ONE_REG(31)
80 /* Restore $1 */
81 STR_LONG_L " $1,"STR_LONGSIZE"(%1)\n\t"
46 ".set pop\n\t" 82 ".set pop\n\t"
47 : "=m" (regs->cp0_epc), 83 : "=m" (regs->cp0_epc)
48 "=m" (regs->regs[29]), "=m" (regs->regs[31]) 84 : "r" (regs->regs)
49 : : "memory"); 85 : "memory");
50} 86}
51 87
52#endif /* _ASM_STACKTRACE_H */ 88#endif /* _ASM_STACKTRACE_H */
diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h
index 7afda4150a59..0673d2d0f2e6 100644
--- a/arch/mips/include/asm/topology.h
+++ b/arch/mips/include/asm/topology.h
@@ -13,7 +13,7 @@
13 13
14#ifdef CONFIG_SMP 14#ifdef CONFIG_SMP
15#define topology_physical_package_id(cpu) (cpu_data[cpu].package) 15#define topology_physical_package_id(cpu) (cpu_data[cpu].package)
16#define topology_core_id(cpu) (cpu_data[cpu].core) 16#define topology_core_id(cpu) (cpu_core(&cpu_data[cpu]))
17#define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) 17#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
18#define topology_sibling_cpumask(cpu) (&cpu_sibling_map[cpu]) 18#define topology_sibling_cpumask(cpu) (&cpu_sibling_map[cpu])
19#endif 19#endif
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h
index d61897535926..6abea5183d7c 100644
--- a/arch/mips/include/uapi/asm/inst.h
+++ b/arch/mips/include/uapi/asm/inst.h
@@ -981,7 +981,7 @@ struct mm16_r3_format { /* Load from global pointer format */
981struct mm16_r5_format { /* Load/store from stack pointer format */ 981struct mm16_r5_format { /* Load/store from stack pointer format */
982 __BITFIELD_FIELD(unsigned int opcode : 6, 982 __BITFIELD_FIELD(unsigned int opcode : 6,
983 __BITFIELD_FIELD(unsigned int rt : 5, 983 __BITFIELD_FIELD(unsigned int rt : 5,
984 __BITFIELD_FIELD(signed int simmediate : 5, 984 __BITFIELD_FIELD(unsigned int imm : 5,
985 __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ 985 __BITFIELD_FIELD(unsigned int : 16, /* Ignored */
986 ;)))) 986 ;))))
987}; 987};
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 46c0581256f1..07f0f4a4b562 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -35,11 +35,15 @@ obj-$(CONFIG_MODULES) += module.o
35obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o 35obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
36obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o 36obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
37 37
38obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o 38sw-y := r4k_switch.o
39obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o 39sw-$(CONFIG_CPU_R3000) := r2300_switch.o
40obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o 40sw-$(CONFIG_CPU_TX39XX) := r2300_switch.o
41obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o 41sw-$(CONFIG_CPU_CAVIUM_OCTEON) := octeon_switch.o
42obj-$(CONFIG_CPU_CAVIUM_OCTEON) += r4k_fpu.o octeon_switch.o 42obj-y += $(sw-y)
43
44obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o
45obj-$(CONFIG_CPU_R3000) += r2300_fpu.o
46obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o
43 47
44obj-$(CONFIG_SMP) += smp.o 48obj-$(CONFIG_SMP) += smp.o
45obj-$(CONFIG_SMP_UP) += smp-up.o 49obj-$(CONFIG_SMP_UP) += smp-up.o
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index b849fe6aad94..d173b49f212d 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -327,8 +327,8 @@ LEAF(mips_cps_get_bootcfg)
327 * to handle contiguous VP numbering, but no such systems yet 327 * to handle contiguous VP numbering, but no such systems yet
328 * exist. 328 * exist.
329 */ 329 */
330 mfc0 t9, $3, 1 330 mfc0 t9, CP0_GLOBALNUMBER
331 andi t9, t9, 0xff 331 andi t9, t9, MIPS_GLOBALNUMBER_VP
332#elif defined(CONFIG_MIPS_MT_SMP) 332#elif defined(CONFIG_MIPS_MT_SMP)
333 has_mt ta2, 1f 333 has_mt ta2, 1f
334 334
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index d08afc7dc507..cf3fd549e16d 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -326,7 +326,7 @@ static int __init fpu_disable(char *s)
326 326
327__setup("nofpu", fpu_disable); 327__setup("nofpu", fpu_disable);
328 328
329int mips_dsp_disabled; 329static int mips_dsp_disabled;
330 330
331static int __init dsp_disable(char *s) 331static int __init dsp_disable(char *s)
332{ 332{
@@ -919,9 +919,12 @@ static void decode_configs(struct cpuinfo_mips *c)
919 919
920#ifndef CONFIG_MIPS_CPS 920#ifndef CONFIG_MIPS_CPS
921 if (cpu_has_mips_r2_r6) { 921 if (cpu_has_mips_r2_r6) {
922 c->core = get_ebase_cpunum(); 922 unsigned int core;
923
924 core = get_ebase_cpunum();
923 if (cpu_has_mipsmt) 925 if (cpu_has_mipsmt)
924 c->core >>= fls(core_nvpes()) - 1; 926 core >>= fls(core_nvpes()) - 1;
927 cpu_set_core(c, core);
925 } 928 }
926#endif 929#endif
927} 930}
@@ -1394,24 +1397,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
1394 MIPS_CPU_DIVEC | MIPS_CPU_LLSC; 1397 MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
1395 c->tlbsize = 48; 1398 c->tlbsize = 48;
1396 break; 1399 break;
1397 case PRID_IMP_R6000:
1398 c->cputype = CPU_R6000;
1399 __cpu_name[cpu] = "R6000";
1400 set_isa(c, MIPS_CPU_ISA_II);
1401 c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
1402 c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
1403 MIPS_CPU_LLSC;
1404 c->tlbsize = 32;
1405 break;
1406 case PRID_IMP_R6000A:
1407 c->cputype = CPU_R6000A;
1408 __cpu_name[cpu] = "R6000A";
1409 set_isa(c, MIPS_CPU_ISA_II);
1410 c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
1411 c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
1412 MIPS_CPU_LLSC;
1413 c->tlbsize = 32;
1414 break;
1415 case PRID_IMP_RM7000: 1400 case PRID_IMP_RM7000:
1416 c->cputype = CPU_RM7000; 1401 c->cputype = CPU_RM7000;
1417 __cpu_name[cpu] = "RM7000"; 1402 __cpu_name[cpu] = "RM7000";
@@ -2113,3 +2098,35 @@ void cpu_report(void)
2113 if (cpu_has_msa) 2098 if (cpu_has_msa)
2114 pr_info("MSA revision is: %08x\n", c->msa_id); 2099 pr_info("MSA revision is: %08x\n", c->msa_id);
2115} 2100}
2101
2102void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster)
2103{
2104 /* Ensure the core number fits in the field */
2105 WARN_ON(cluster > (MIPS_GLOBALNUMBER_CLUSTER >>
2106 MIPS_GLOBALNUMBER_CLUSTER_SHF));
2107
2108 cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CLUSTER;
2109 cpuinfo->globalnumber |= cluster << MIPS_GLOBALNUMBER_CLUSTER_SHF;
2110}
2111
2112void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core)
2113{
2114 /* Ensure the core number fits in the field */
2115 WARN_ON(core > (MIPS_GLOBALNUMBER_CORE >> MIPS_GLOBALNUMBER_CORE_SHF));
2116
2117 cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CORE;
2118 cpuinfo->globalnumber |= core << MIPS_GLOBALNUMBER_CORE_SHF;
2119}
2120
2121void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe)
2122{
2123 /* Ensure the VP(E) ID fits in the field */
2124 WARN_ON(vpe > (MIPS_GLOBALNUMBER_VP >> MIPS_GLOBALNUMBER_VP_SHF));
2125
2126 /* Ensure we're not using VP(E)s without support */
2127 WARN_ON(vpe && !IS_ENABLED(CONFIG_MIPS_MT_SMP) &&
2128 !IS_ENABLED(CONFIG_CPU_MIPSR6));
2129
2130 cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_VP;
2131 cpuinfo->globalnumber |= vpe << MIPS_GLOBALNUMBER_VP_SHF;
2132}
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index ae810da4d499..37b9383eacd3 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -150,6 +150,7 @@ LEAF(__r4k_wait)
150 .align 5 150 .align 5
151BUILD_ROLLBACK_PROLOGUE handle_int 151BUILD_ROLLBACK_PROLOGUE handle_int
152NESTED(handle_int, PT_SIZE, sp) 152NESTED(handle_int, PT_SIZE, sp)
153 .cfi_signal_frame
153#ifdef CONFIG_TRACE_IRQFLAGS 154#ifdef CONFIG_TRACE_IRQFLAGS
154 /* 155 /*
155 * Check to see if the interrupted code has just disabled 156 * Check to see if the interrupted code has just disabled
@@ -181,7 +182,7 @@ NESTED(handle_int, PT_SIZE, sp)
1811: 1821:
182 .set pop 183 .set pop
183#endif 184#endif
184 SAVE_ALL 185 SAVE_ALL docfi=1
185 CLI 186 CLI
186 TRACE_IRQS_OFF 187 TRACE_IRQS_OFF
187 188
@@ -269,8 +270,8 @@ NESTED(except_vec_ejtag_debug, 0, sp)
269 */ 270 */
270BUILD_ROLLBACK_PROLOGUE except_vec_vi 271BUILD_ROLLBACK_PROLOGUE except_vec_vi
271NESTED(except_vec_vi, 0, sp) 272NESTED(except_vec_vi, 0, sp)
272 SAVE_SOME 273 SAVE_SOME docfi=1
273 SAVE_AT 274 SAVE_AT docfi=1
274 .set push 275 .set push
275 .set noreorder 276 .set noreorder
276 PTR_LA v1, except_vec_vi_handler 277 PTR_LA v1, except_vec_vi_handler
@@ -396,6 +397,7 @@ NESTED(except_vec_nmi, 0, sp)
396 __FINIT 397 __FINIT
397 398
398NESTED(nmi_handler, PT_SIZE, sp) 399NESTED(nmi_handler, PT_SIZE, sp)
400 .cfi_signal_frame
399 .set push 401 .set push
400 .set noat 402 .set noat
401 /* 403 /*
@@ -478,6 +480,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
478 .macro __BUILD_HANDLER exception handler clear verbose ext 480 .macro __BUILD_HANDLER exception handler clear verbose ext
479 .align 5 481 .align 5
480 NESTED(handle_\exception, PT_SIZE, sp) 482 NESTED(handle_\exception, PT_SIZE, sp)
483 .cfi_signal_frame
481 .set noat 484 .set noat
482 SAVE_ALL 485 SAVE_ALL
483 FEXPORT(handle_\exception\ext) 486 FEXPORT(handle_\exception\ext)
@@ -485,8 +488,8 @@ NESTED(nmi_handler, PT_SIZE, sp)
485 .set at 488 .set at
486 __BUILD_\verbose \exception 489 __BUILD_\verbose \exception
487 move a0, sp 490 move a0, sp
488 PTR_LA ra, ret_from_exception 491 jal do_\handler
489 j do_\handler 492 j ret_from_exception
490 END(handle_\exception) 493 END(handle_\exception)
491 .endm 494 .endm
492 495
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
index 60ab4c44d305..7c246b69c545 100644
--- a/arch/mips/kernel/idle.c
+++ b/arch/mips/kernel/idle.c
@@ -11,6 +11,7 @@
11 * as published by the Free Software Foundation; either version 11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version. 12 * 2 of the License, or (at your option) any later version.
13 */ 13 */
14#include <linux/cpu.h>
14#include <linux/export.h> 15#include <linux/export.h>
15#include <linux/init.h> 16#include <linux/init.h>
16#include <linux/irqflags.h> 17#include <linux/irqflags.h>
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index cb0c57f860d4..e91c8c4e2eb5 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -12,10 +12,10 @@
12#include <linux/percpu.h> 12#include <linux/percpu.h>
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14 14
15#include <asm/mips-cm.h> 15#include <asm/mips-cps.h>
16#include <asm/mipsregs.h> 16#include <asm/mipsregs.h>
17 17
18void __iomem *mips_cm_base; 18void __iomem *mips_gcr_base;
19void __iomem *mips_cm_l2sync_base; 19void __iomem *mips_cm_l2sync_base;
20int mips_cm_is64; 20int mips_cm_is64;
21 21
@@ -167,8 +167,8 @@ phys_addr_t __mips_cm_l2sync_phys_base(void)
167 * current location. 167 * current location.
168 */ 168 */
169 base_reg = read_gcr_l2_only_sync_base(); 169 base_reg = read_gcr_l2_only_sync_base();
170 if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK) 170 if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN)
171 return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK; 171 return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE;
172 172
173 /* Default to following the CM */ 173 /* Default to following the CM */
174 return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; 174 return mips_cm_phys_base() + MIPS_CM_GCR_SIZE;
@@ -183,19 +183,19 @@ static void mips_cm_probe_l2sync(void)
183 phys_addr_t addr; 183 phys_addr_t addr;
184 184
185 /* L2-only sync was introduced with CM major revision 6 */ 185 /* L2-only sync was introduced with CM major revision 6 */
186 major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> 186 major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR) >>
187 CM_GCR_REV_MAJOR_SHF; 187 __ffs(CM_GCR_REV_MAJOR);
188 if (major_rev < 6) 188 if (major_rev < 6)
189 return; 189 return;
190 190
191 /* Find a location for the L2 sync region */ 191 /* Find a location for the L2 sync region */
192 addr = mips_cm_l2sync_phys_base(); 192 addr = mips_cm_l2sync_phys_base();
193 BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK) != addr); 193 BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE) != addr);
194 if (!addr) 194 if (!addr)
195 return; 195 return;
196 196
197 /* Set the region base address & enable it */ 197 /* Set the region base address & enable it */
198 write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK); 198 write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN);
199 199
200 /* Map the region */ 200 /* Map the region */
201 mips_cm_l2sync_base = ioremap_nocache(addr, MIPS_CM_L2SYNC_SIZE); 201 mips_cm_l2sync_base = ioremap_nocache(addr, MIPS_CM_L2SYNC_SIZE);
@@ -211,41 +211,39 @@ int mips_cm_probe(void)
211 * No need to probe again if we have already been 211 * No need to probe again if we have already been
212 * here before. 212 * here before.
213 */ 213 */
214 if (mips_cm_base) 214 if (mips_gcr_base)
215 return 0; 215 return 0;
216 216
217 addr = mips_cm_phys_base(); 217 addr = mips_cm_phys_base();
218 BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr); 218 BUG_ON((addr & CM_GCR_BASE_GCRBASE) != addr);
219 if (!addr) 219 if (!addr)
220 return -ENODEV; 220 return -ENODEV;
221 221
222 mips_cm_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE); 222 mips_gcr_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE);
223 if (!mips_cm_base) 223 if (!mips_gcr_base)
224 return -ENXIO; 224 return -ENXIO;
225 225
226 /* sanity check that we're looking at a CM */ 226 /* sanity check that we're looking at a CM */
227 base_reg = read_gcr_base(); 227 base_reg = read_gcr_base();
228 if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) { 228 if ((base_reg & CM_GCR_BASE_GCRBASE) != addr) {
229 pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n", 229 pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n",
230 (unsigned long)addr); 230 (unsigned long)addr);
231 mips_cm_base = NULL; 231 mips_gcr_base = NULL;
232 return -ENODEV; 232 return -ENODEV;
233 } 233 }
234 234
235 /* set default target to memory */ 235 /* set default target to memory */
236 base_reg &= ~CM_GCR_BASE_CMDEFTGT_MSK; 236 change_gcr_base(CM_GCR_BASE_CMDEFTGT, CM_GCR_BASE_CMDEFTGT_MEM);
237 base_reg |= CM_GCR_BASE_CMDEFTGT_MEM;
238 write_gcr_base(base_reg);
239 237
240 /* disable CM regions */ 238 /* disable CM regions */
241 write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR_MSK); 239 write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
242 write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); 240 write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK);
243 write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR_MSK); 241 write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR);
244 write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); 242 write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK);
245 write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR_MSK); 243 write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR);
246 write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); 244 write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK);
247 write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR_MSK); 245 write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR);
248 write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); 246 write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK);
249 247
250 /* probe for an L2-only sync region */ 248 /* probe for an L2-only sync region */
251 mips_cm_probe_l2sync(); 249 mips_cm_probe_l2sync();
@@ -259,16 +257,27 @@ int mips_cm_probe(void)
259 return 0; 257 return 0;
260} 258}
261 259
262void mips_cm_lock_other(unsigned int core, unsigned int vp) 260void mips_cm_lock_other(unsigned int cluster, unsigned int core,
261 unsigned int vp, unsigned int block)
263{ 262{
264 unsigned curr_core; 263 unsigned int curr_core, cm_rev;
265 u32 val; 264 u32 val;
266 265
266 cm_rev = mips_cm_revision();
267 preempt_disable(); 267 preempt_disable();
268 268
269 if (mips_cm_revision() >= CM_REV_CM3) { 269 if (cm_rev >= CM_REV_CM3) {
270 val = core << CM3_GCR_Cx_OTHER_CORE_SHF; 270 val = core << __ffs(CM3_GCR_Cx_OTHER_CORE);
271 val |= vp << CM3_GCR_Cx_OTHER_VP_SHF; 271 val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP);
272
273 if (cm_rev >= CM_REV_CM3_5) {
274 val |= CM_GCR_Cx_OTHER_CLUSTER_EN;
275 val |= cluster << __ffs(CM_GCR_Cx_OTHER_CLUSTER);
276 val |= block << __ffs(CM_GCR_Cx_OTHER_BLOCK);
277 } else {
278 WARN_ON(cluster != 0);
279 WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL);
280 }
272 281
273 /* 282 /*
274 * We need to disable interrupts in SMP systems in order to 283 * We need to disable interrupts in SMP systems in order to
@@ -282,18 +291,20 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
282 spin_lock_irqsave(this_cpu_ptr(&cm_core_lock), 291 spin_lock_irqsave(this_cpu_ptr(&cm_core_lock),
283 *this_cpu_ptr(&cm_core_lock_flags)); 292 *this_cpu_ptr(&cm_core_lock_flags));
284 } else { 293 } else {
294 WARN_ON(cluster != 0);
285 WARN_ON(vp != 0); 295 WARN_ON(vp != 0);
296 WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL);
286 297
287 /* 298 /*
288 * We only have a GCR_CL_OTHER per core in systems with 299 * We only have a GCR_CL_OTHER per core in systems with
289 * CM 2.5 & older, so have to ensure other VP(E)s don't 300 * CM 2.5 & older, so have to ensure other VP(E)s don't
290 * race with us. 301 * race with us.
291 */ 302 */
292 curr_core = current_cpu_data.core; 303 curr_core = cpu_core(&current_cpu_data);
293 spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core), 304 spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core),
294 per_cpu(cm_core_lock_flags, curr_core)); 305 per_cpu(cm_core_lock_flags, curr_core));
295 306
296 val = core << CM_GCR_Cx_OTHER_CORENUM_SHF; 307 val = core << __ffs(CM_GCR_Cx_OTHER_CORENUM);
297 } 308 }
298 309
299 write_gcr_cl_other(val); 310 write_gcr_cl_other(val);
@@ -310,7 +321,7 @@ void mips_cm_unlock_other(void)
310 unsigned int curr_core; 321 unsigned int curr_core;
311 322
312 if (mips_cm_revision() < CM_REV_CM3) { 323 if (mips_cm_revision() < CM_REV_CM3) {
313 curr_core = current_cpu_data.core; 324 curr_core = cpu_core(&current_cpu_data);
314 spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core), 325 spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core),
315 per_cpu(cm_core_lock_flags, curr_core)); 326 per_cpu(cm_core_lock_flags, curr_core));
316 } else { 327 } else {
@@ -332,13 +343,13 @@ void mips_cm_error_report(void)
332 return; 343 return;
333 344
334 revision = mips_cm_revision(); 345 revision = mips_cm_revision();
346 cm_error = read_gcr_error_cause();
347 cm_addr = read_gcr_error_addr();
348 cm_other = read_gcr_error_mult();
335 349
336 if (revision < CM_REV_CM3) { /* CM2 */ 350 if (revision < CM_REV_CM3) { /* CM2 */
337 cm_error = read_gcr_error_cause(); 351 cause = cm_error >> __ffs(CM_GCR_ERROR_CAUSE_ERRTYPE);
338 cm_addr = read_gcr_error_addr(); 352 ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND);
339 cm_other = read_gcr_error_mult();
340 cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
341 ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
342 353
343 if (!cause) 354 if (!cause)
344 return; 355 return;
@@ -380,11 +391,8 @@ void mips_cm_error_report(void)
380 ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits; 391 ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
381 ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit; 392 ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
382 393
383 cm_error = read64_gcr_error_cause(); 394 cause = cm_error >> __ffs64(CM3_GCR_ERROR_CAUSE_ERRTYPE);
384 cm_addr = read64_gcr_error_addr(); 395 ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND);
385 cm_other = read64_gcr_error_mult();
386 cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF;
387 ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
388 396
389 if (!cause) 397 if (!cause)
390 return; 398 return;
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index a4964c334cab..f66b05ebf637 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -12,8 +12,7 @@
12#include <linux/percpu.h> 12#include <linux/percpu.h>
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14 14
15#include <asm/mips-cm.h> 15#include <asm/mips-cps.h>
16#include <asm/mips-cpc.h>
17 16
18void __iomem *mips_cpc_base; 17void __iomem *mips_cpc_base;
19 18
@@ -40,13 +39,13 @@ static phys_addr_t mips_cpc_phys_base(void)
40 if (!mips_cm_present()) 39 if (!mips_cm_present())
41 return 0; 40 return 0;
42 41
43 if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX_MSK)) 42 if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX))
44 return 0; 43 return 0;
45 44
46 /* If the CPC is already enabled, leave it so */ 45 /* If the CPC is already enabled, leave it so */
47 cpc_base = read_gcr_cpc_base(); 46 cpc_base = read_gcr_cpc_base();
48 if (cpc_base & CM_GCR_CPC_BASE_CPCEN_MSK) 47 if (cpc_base & CM_GCR_CPC_BASE_CPCEN)
49 return cpc_base & CM_GCR_CPC_BASE_CPCBASE_MSK; 48 return cpc_base & CM_GCR_CPC_BASE_CPCBASE;
50 49
51 /* Otherwise, use the default address */ 50 /* Otherwise, use the default address */
52 cpc_base = mips_cpc_default_phys_base(); 51 cpc_base = mips_cpc_default_phys_base();
@@ -54,7 +53,7 @@ static phys_addr_t mips_cpc_phys_base(void)
54 return cpc_base; 53 return cpc_base;
55 54
56 /* Enable the CPC, mapped at the default address */ 55 /* Enable the CPC, mapped at the default address */
57 write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN_MSK); 56 write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN);
58 return cpc_base; 57 return cpc_base;
59} 58}
60 59
@@ -86,10 +85,10 @@ void mips_cpc_lock_other(unsigned int core)
86 return; 85 return;
87 86
88 preempt_disable(); 87 preempt_disable();
89 curr_core = current_cpu_data.core; 88 curr_core = cpu_core(&current_cpu_data);
90 spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), 89 spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core),
91 per_cpu(cpc_core_lock_flags, curr_core)); 90 per_cpu(cpc_core_lock_flags, curr_core));
92 write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF); 91 write_cpc_cl_other(core << __ffs(CPC_Cx_OTHER_CORENUM));
93 92
94 /* 93 /*
95 * Ensure the core-other region reflects the appropriate core & 94 * Ensure the core-other region reflects the appropriate core &
@@ -106,7 +105,7 @@ void mips_cpc_unlock_other(void)
106 /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */ 105 /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */
107 return; 106 return;
108 107
109 curr_core = current_cpu_data.core; 108 curr_core = cpu_core(&current_cpu_data);
110 spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core), 109 spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core),
111 per_cpu(cpc_core_lock_flags, curr_core)); 110 per_cpu(cpc_core_lock_flags, curr_core));
112 preempt_enable(); 111 preempt_enable();
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c
index ae64c8f56a8c..eb18b186e858 100644
--- a/arch/mips/kernel/mips-r2-to-r6-emul.c
+++ b/arch/mips/kernel/mips-r2-to-r6-emul.c
@@ -46,9 +46,11 @@
46#define LL "ll " 46#define LL "ll "
47#define SC "sc " 47#define SC "sc "
48 48
49DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2emustats); 49#ifdef CONFIG_DEBUG_FS
50DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2bdemustats); 50static DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2emustats);
51DEFINE_PER_CPU(struct mips_r2br_emulator_stats, mipsr2bremustats); 51static DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2bdemustats);
52static DEFINE_PER_CPU(struct mips_r2br_emulator_stats, mipsr2bremustats);
53#endif
52 54
53extern const unsigned int fpucondbit[8]; 55extern const unsigned int fpucondbit[8];
54 56
@@ -600,7 +602,7 @@ static int ddivu_func(struct pt_regs *regs, u32 ir)
600} 602}
601 603
602/* R6 removed instructions for the SPECIAL opcode */ 604/* R6 removed instructions for the SPECIAL opcode */
603static struct r2_decoder_table spec_op_table[] = { 605static const struct r2_decoder_table spec_op_table[] = {
604 { 0xfc1ff83f, 0x00000008, jr_func }, 606 { 0xfc1ff83f, 0x00000008, jr_func },
605 { 0xfc00ffff, 0x00000018, mult_func }, 607 { 0xfc00ffff, 0x00000018, mult_func },
606 { 0xfc00ffff, 0x00000019, multu_func }, 608 { 0xfc00ffff, 0x00000019, multu_func },
@@ -867,7 +869,7 @@ static int dclo_func(struct pt_regs *regs, u32 ir)
867} 869}
868 870
869/* R6 removed instructions for the SPECIAL2 opcode */ 871/* R6 removed instructions for the SPECIAL2 opcode */
870static struct r2_decoder_table spec2_op_table[] = { 872static const struct r2_decoder_table spec2_op_table[] = {
871 { 0xfc00ffff, 0x70000000, madd_func }, 873 { 0xfc00ffff, 0x70000000, madd_func },
872 { 0xfc00ffff, 0x70000001, maddu_func }, 874 { 0xfc00ffff, 0x70000001, maddu_func },
873 { 0xfc0007ff, 0x70000002, mul_func }, 875 { 0xfc0007ff, 0x70000002, mul_func },
@@ -881,9 +883,9 @@ static struct r2_decoder_table spec2_op_table[] = {
881}; 883};
882 884
883static inline int mipsr2_find_op_func(struct pt_regs *regs, u32 inst, 885static inline int mipsr2_find_op_func(struct pt_regs *regs, u32 inst,
884 struct r2_decoder_table *table) 886 const struct r2_decoder_table *table)
885{ 887{
886 struct r2_decoder_table *p; 888 const struct r2_decoder_table *p;
887 int err; 889 int err;
888 890
889 for (p = table; p->func; p++) { 891 for (p = table; p->func; p++) {
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index 3375745b9198..e42113fe2762 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -10,12 +10,13 @@
10 * Copyright (C) 2000 MIPS Technologies, Inc. 10 * Copyright (C) 2000 MIPS Technologies, Inc.
11 * written by Carsten Langgaard, carstenl@mips.com 11 * written by Carsten Langgaard, carstenl@mips.com
12 */ 12 */
13#include <asm/asm.h>
14#include <asm/export.h>
15#include <asm/asm-offsets.h>
16#include <asm/mipsregs.h>
17#include <asm/regdef.h>
18#include <asm/stackframe.h>
13 19
14#define USE_ALTERNATE_RESUME_IMPL 1
15 .set push
16 .set arch=mips64r2
17#include "r4k_switch.S"
18 .set pop
19/* 20/*
20 * task_struct *resume(task_struct *prev, task_struct *next, 21 * task_struct *resume(task_struct *prev, task_struct *next,
21 * struct thread_info *next_ti) 22 * struct thread_info *next_ti)
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index d99416094ba9..4655017f2377 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -17,8 +17,7 @@
17#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
18#include <asm/cacheops.h> 18#include <asm/cacheops.h>
19#include <asm/idle.h> 19#include <asm/idle.h>
20#include <asm/mips-cm.h> 20#include <asm/mips-cps.h>
21#include <asm/mips-cpc.h>
22#include <asm/mipsmtregs.h> 21#include <asm/mipsmtregs.h>
23#include <asm/pm.h> 22#include <asm/pm.h>
24#include <asm/pm-cps.h> 23#include <asm/pm-cps.h>
@@ -49,7 +48,7 @@ static DEFINE_PER_CPU_READ_MOSTLY(cps_nc_entry_fn[CPS_PM_STATE_COUNT],
49 nc_asm_enter); 48 nc_asm_enter);
50 49
51/* Bitmap indicating which states are supported by the system */ 50/* Bitmap indicating which states are supported by the system */
52DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT); 51static DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT);
53 52
54/* 53/*
55 * Indicates the number of coupled VPEs ready to operate in a non-coherent 54 * Indicates the number of coupled VPEs ready to operate in a non-coherent
@@ -114,7 +113,7 @@ static void coupled_barrier(atomic_t *a, unsigned online)
114int cps_pm_enter_state(enum cps_pm_state state) 113int cps_pm_enter_state(enum cps_pm_state state)
115{ 114{
116 unsigned cpu = smp_processor_id(); 115 unsigned cpu = smp_processor_id();
117 unsigned core = current_cpu_data.core; 116 unsigned core = cpu_core(&current_cpu_data);
118 unsigned online, left; 117 unsigned online, left;
119 cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled); 118 cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled);
120 u32 *core_ready_count, *nc_core_ready_count; 119 u32 *core_ready_count, *nc_core_ready_count;
@@ -486,7 +485,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
486 * defined by the interAptiv & proAptiv SUMs as ensuring that the 485 * defined by the interAptiv & proAptiv SUMs as ensuring that the
487 * operation resulting from the preceding store is complete. 486 * operation resulting from the preceding store is complete.
488 */ 487 */
489 uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); 488 uasm_i_addiu(&p, t0, zero, 1 << cpu_core(&cpu_data[cpu]));
490 uasm_i_sw(&p, t0, 0, r_pcohctl); 489 uasm_i_sw(&p, t0, 0, r_pcohctl);
491 uasm_i_lw(&p, t0, 0, r_pcohctl); 490 uasm_i_lw(&p, t0, 0, r_pcohctl);
492 491
@@ -569,8 +568,8 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
569 * rest will just be performing a rather unusual nop. 568 * rest will just be performing a rather unusual nop.
570 */ 569 */
571 uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3 570 uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3
572 ? CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK 571 ? CM_GCR_Cx_COHERENCE_COHDOMAINEN
573 : CM3_GCR_Cx_COHERENCE_COHEN_MSK); 572 : CM3_GCR_Cx_COHERENCE_COHEN);
574 573
575 uasm_i_sw(&p, t0, 0, r_pcohctl); 574 uasm_i_sw(&p, t0, 0, r_pcohctl);
576 uasm_i_lw(&p, t0, 0, r_pcohctl); 575 uasm_i_lw(&p, t0, 0, r_pcohctl);
@@ -640,7 +639,7 @@ out_err:
640static int cps_pm_online_cpu(unsigned int cpu) 639static int cps_pm_online_cpu(unsigned int cpu)
641{ 640{
642 enum cps_pm_state state; 641 enum cps_pm_state state;
643 unsigned core = cpu_data[cpu].core; 642 unsigned core = cpu_core(&cpu_data[cpu]);
644 void *entry_fn, *core_rc; 643 void *entry_fn, *core_rc;
645 644
646 for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) { 645 for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) {
@@ -692,7 +691,7 @@ static int __init cps_pm_init(void)
692 /* Detect whether a CPC is present */ 691 /* Detect whether a CPC is present */
693 if (mips_cpc_present()) { 692 if (mips_cpc_present()) {
694 /* Detect whether clock gating is implemented */ 693 /* Detect whether clock gating is implemented */
695 if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK) 694 if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL)
696 set_bit(CPS_PM_CLOCK_GATED, state_support); 695 set_bit(CPS_PM_CLOCK_GATED, state_support);
697 else 696 else
698 pr_warn("pm-cps: CPC does not support clock gating\n"); 697 pr_warn("pm-cps: CPC does not support clock gating\n");
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 70604c753aa4..bd9bf528f19b 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -134,13 +134,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
134 seq_printf(m, "kscratch registers\t: %d\n", 134 seq_printf(m, "kscratch registers\t: %d\n",
135 hweight8(cpu_data[n].kscratch_mask)); 135 hweight8(cpu_data[n].kscratch_mask));
136 seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package); 136 seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package);
137 seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); 137 seq_printf(m, "core\t\t\t: %d\n", cpu_core(&cpu_data[n]));
138 138
139#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) 139#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
140 if (cpu_has_mipsmt) 140 if (cpu_has_mipsmt)
141 seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); 141 seq_printf(m, "VPE\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n]));
142 else if (cpu_has_vp) 142 else if (cpu_has_vp)
143 seq_printf(m, "VP\t\t\t: %d\n", cpu_data[n].vpe_id); 143 seq_printf(m, "VP\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n]));
144#endif 144#endif
145 145
146 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", 146 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 5351e1f3950d..c5ff6bfe2825 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -208,13 +208,13 @@ static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
208 * 208 *
209 * microMIPS is way more fun... 209 * microMIPS is way more fun...
210 */ 210 */
211 if (mm_insn_16bit(ip->halfword[1])) { 211 if (mm_insn_16bit(ip->word >> 16)) {
212 switch (ip->mm16_r5_format.opcode) { 212 switch (ip->mm16_r5_format.opcode) {
213 case mm_swsp16_op: 213 case mm_swsp16_op:
214 if (ip->mm16_r5_format.rt != 31) 214 if (ip->mm16_r5_format.rt != 31)
215 return 0; 215 return 0;
216 216
217 *poff = ip->mm16_r5_format.simmediate; 217 *poff = ip->mm16_r5_format.imm;
218 *poff = (*poff << 2) / sizeof(ulong); 218 *poff = (*poff << 2) / sizeof(ulong);
219 return 1; 219 return 1;
220 220
@@ -287,7 +287,7 @@ static inline int is_jump_ins(union mips_instruction *ip)
287 * 287 *
288 * microMIPS is kind of more fun... 288 * microMIPS is kind of more fun...
289 */ 289 */
290 if (mm_insn_16bit(ip->halfword[1])) { 290 if (mm_insn_16bit(ip->word >> 16)) {
291 if ((ip->mm16_r5_format.opcode == mm_pool16c_op && 291 if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
292 (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op)) 292 (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op))
293 return 1; 293 return 1;
@@ -313,9 +313,11 @@ static inline int is_jump_ins(union mips_instruction *ip)
313#endif 313#endif
314} 314}
315 315
316static inline int is_sp_move_ins(union mips_instruction *ip) 316static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size)
317{ 317{
318#ifdef CONFIG_CPU_MICROMIPS 318#ifdef CONFIG_CPU_MICROMIPS
319 unsigned short tmp;
320
319 /* 321 /*
320 * addiusp -imm 322 * addiusp -imm
321 * addius5 sp,-imm 323 * addius5 sp,-imm
@@ -324,21 +326,40 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
324 * 326 *
325 * microMIPS is not more fun... 327 * microMIPS is not more fun...
326 */ 328 */
327 if (mm_insn_16bit(ip->halfword[1])) { 329 if (mm_insn_16bit(ip->word >> 16)) {
328 return (ip->mm16_r3_format.opcode == mm_pool16d_op && 330 if (ip->mm16_r3_format.opcode == mm_pool16d_op &&
329 ip->mm16_r3_format.simmediate && mm_addiusp_func) || 331 ip->mm16_r3_format.simmediate & mm_addiusp_func) {
330 (ip->mm16_r5_format.opcode == mm_pool16d_op && 332 tmp = ip->mm_b0_format.simmediate >> 1;
331 ip->mm16_r5_format.rt == 29); 333 tmp = ((tmp & 0x1ff) ^ 0x100) - 0x100;
334 if ((tmp + 2) < 4) /* 0x0,0x1,0x1fe,0x1ff are special */
335 tmp ^= 0x100;
336 *frame_size = -(signed short)(tmp << 2);
337 return 1;
338 }
339 if (ip->mm16_r5_format.opcode == mm_pool16d_op &&
340 ip->mm16_r5_format.rt == 29) {
341 tmp = ip->mm16_r5_format.imm >> 1;
342 *frame_size = -(signed short)(tmp & 0xf);
343 return 1;
344 }
345 return 0;
332 } 346 }
333 347
334 return ip->mm_i_format.opcode == mm_addiu32_op && 348 if (ip->mm_i_format.opcode == mm_addiu32_op &&
335 ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; 349 ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29) {
350 *frame_size = -ip->i_format.simmediate;
351 return 1;
352 }
336#else 353#else
337 /* addiu/daddiu sp,sp,-imm */ 354 /* addiu/daddiu sp,sp,-imm */
338 if (ip->i_format.rs != 29 || ip->i_format.rt != 29) 355 if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
339 return 0; 356 return 0;
340 if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) 357
358 if (ip->i_format.opcode == addiu_op ||
359 ip->i_format.opcode == daddiu_op) {
360 *frame_size = -ip->i_format.simmediate;
341 return 1; 361 return 1;
362 }
342#endif 363#endif
343 return 0; 364 return 0;
344} 365}
@@ -348,7 +369,9 @@ static int get_frame_info(struct mips_frame_info *info)
348 bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS); 369 bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
349 union mips_instruction insn, *ip, *ip_end; 370 union mips_instruction insn, *ip, *ip_end;
350 const unsigned int max_insns = 128; 371 const unsigned int max_insns = 128;
372 unsigned int last_insn_size = 0;
351 unsigned int i; 373 unsigned int i;
374 bool saw_jump = false;
352 375
353 info->pc_offset = -1; 376 info->pc_offset = -1;
354 info->frame_size = 0; 377 info->frame_size = 0;
@@ -359,47 +382,44 @@ static int get_frame_info(struct mips_frame_info *info)
359 382
360 ip_end = (void *)ip + info->func_size; 383 ip_end = (void *)ip + info->func_size;
361 384
362 for (i = 0; i < max_insns && ip < ip_end; i++, ip++) { 385 for (i = 0; i < max_insns && ip < ip_end; i++) {
386 ip = (void *)ip + last_insn_size;
363 if (is_mmips && mm_insn_16bit(ip->halfword[0])) { 387 if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
364 insn.halfword[0] = 0; 388 insn.word = ip->halfword[0] << 16;
365 insn.halfword[1] = ip->halfword[0]; 389 last_insn_size = 2;
366 } else if (is_mmips) { 390 } else if (is_mmips) {
367 insn.halfword[0] = ip->halfword[1]; 391 insn.word = ip->halfword[0] << 16 | ip->halfword[1];
368 insn.halfword[1] = ip->halfword[0]; 392 last_insn_size = 4;
369 } else { 393 } else {
370 insn.word = ip->word; 394 insn.word = ip->word;
395 last_insn_size = 4;
371 } 396 }
372 397
373 if (is_jump_ins(&insn))
374 break;
375
376 if (!info->frame_size) { 398 if (!info->frame_size) {
377 if (is_sp_move_ins(&insn)) 399 is_sp_move_ins(&insn, &info->frame_size);
378 { 400 continue;
379#ifdef CONFIG_CPU_MICROMIPS 401 } else if (!saw_jump && is_jump_ins(ip)) {
380 if (mm_insn_16bit(ip->halfword[0])) 402 /*
381 { 403 * If we see a jump instruction, we are finished
382 unsigned short tmp; 404 * with the frame save.
383 405 *
384 if (ip->halfword[0] & mm_addiusp_func) 406 * Some functions can have a shortcut return at
385 { 407 * the beginning of the function, so don't start
386 tmp = (((ip->halfword[0] >> 1) & 0x1ff) << 2); 408 * looking for jump instruction until we see the
387 info->frame_size = -(signed short)(tmp | ((tmp & 0x100) ? 0xfe00 : 0)); 409 * frame setup.
388 } else { 410 *
389 tmp = (ip->halfword[0] >> 1); 411 * The RA save instruction can get put into the
390 info->frame_size = -(signed short)(tmp & 0xf); 412 * delay slot of the jump instruction, so look
391 } 413 * at the next instruction, too.
392 ip = (void *) &ip->halfword[1]; 414 */
393 ip--; 415 saw_jump = true;
394 } else
395#endif
396 info->frame_size = - ip->i_format.simmediate;
397 }
398 continue; 416 continue;
399 } 417 }
400 if (info->pc_offset == -1 && 418 if (info->pc_offset == -1 &&
401 is_ra_save_ins(&insn, &info->pc_offset)) 419 is_ra_save_ins(&insn, &info->pc_offset))
402 break; 420 break;
421 if (saw_jump)
422 break;
403 } 423 }
404 if (info->frame_size && info->pc_offset >= 0) /* nested */ 424 if (info->frame_size && info->pc_offset >= 0) /* nested */
405 return 0; 425 return 0;
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
index 918f2f6d3861..3062ba66c563 100644
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -12,7 +12,9 @@
12 * Copyright (c) 1998 Harald Koerfgen 12 * Copyright (c) 1998 Harald Koerfgen
13 */ 13 */
14#include <asm/asm.h> 14#include <asm/asm.h>
15#include <asm/asmmacro.h>
15#include <asm/errno.h> 16#include <asm/errno.h>
17#include <asm/export.h>
16#include <asm/fpregdef.h> 18#include <asm/fpregdef.h>
17#include <asm/mipsregs.h> 19#include <asm/mipsregs.h>
18#include <asm/asm-offsets.h> 20#include <asm/asm-offsets.h>
@@ -31,9 +33,85 @@
31 PTR 9b+4,bad_stack; \ 33 PTR 9b+4,bad_stack; \
32 .previous 34 .previous
33 35
34 .set noreorder
35 .set mips1 36 .set mips1
36 37
38/*
39 * Save a thread's fp context.
40 */
41LEAF(_save_fp)
42EXPORT_SYMBOL(_save_fp)
43 fpu_save_single a0, t1 # clobbers t1
44 jr ra
45 END(_save_fp)
46
47/*
48 * Restore a thread's fp context.
49 */
50LEAF(_restore_fp)
51 fpu_restore_single a0, t1 # clobbers t1
52 jr ra
53 END(_restore_fp)
54
55/*
56 * Load the FPU with signalling NANS. This bit pattern we're using has
57 * the property that no matter whether considered as single or as double
58 * precision represents signaling NANS.
59 *
60 * The value to initialize fcr31 to comes in $a0.
61 */
62
63 .set push
64 SET_HARDFLOAT
65
66LEAF(_init_fpu)
67 mfc0 t0, CP0_STATUS
68 li t1, ST0_CU1
69 or t0, t1
70 mtc0 t0, CP0_STATUS
71
72 ctc1 a0, fcr31
73
74 li t0, -1
75
76 mtc1 t0, $f0
77 mtc1 t0, $f1
78 mtc1 t0, $f2
79 mtc1 t0, $f3
80 mtc1 t0, $f4
81 mtc1 t0, $f5
82 mtc1 t0, $f6
83 mtc1 t0, $f7
84 mtc1 t0, $f8
85 mtc1 t0, $f9
86 mtc1 t0, $f10
87 mtc1 t0, $f11
88 mtc1 t0, $f12
89 mtc1 t0, $f13
90 mtc1 t0, $f14
91 mtc1 t0, $f15
92 mtc1 t0, $f16
93 mtc1 t0, $f17
94 mtc1 t0, $f18
95 mtc1 t0, $f19
96 mtc1 t0, $f20
97 mtc1 t0, $f21
98 mtc1 t0, $f22
99 mtc1 t0, $f23
100 mtc1 t0, $f24
101 mtc1 t0, $f25
102 mtc1 t0, $f26
103 mtc1 t0, $f27
104 mtc1 t0, $f28
105 mtc1 t0, $f29
106 mtc1 t0, $f30
107 mtc1 t0, $f31
108 jr ra
109 END(_init_fpu)
110
111 .set pop
112
113 .set noreorder
114
37/** 115/**
38 * _save_fp_context() - save FP context from the FPU 116 * _save_fp_context() - save FP context from the FPU
39 * @a0 - pointer to fpregs field of sigcontext 117 * @a0 - pointer to fpregs field of sigcontext
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 1049eeafd97d..e57703b1de50 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -26,12 +26,6 @@
26 .align 5 26 .align 5
27 27
28/* 28/*
29 * Offset to the current process status flags, the first 32 bytes of the
30 * stack are not used.
31 */
32#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
33
34/*
35 * task_struct *resume(task_struct *prev, task_struct *next, 29 * task_struct *resume(task_struct *prev, task_struct *next,
36 * struct thread_info *next_ti) 30 * struct thread_info *next_ti)
37 */ 31 */
@@ -68,78 +62,3 @@ LEAF(resume)
68 move v0, a0 62 move v0, a0
69 jr ra 63 jr ra
70 END(resume) 64 END(resume)
71
72/*
73 * Save a thread's fp context.
74 */
75LEAF(_save_fp)
76EXPORT_SYMBOL(_save_fp)
77 fpu_save_single a0, t1 # clobbers t1
78 jr ra
79 END(_save_fp)
80
81/*
82 * Restore a thread's fp context.
83 */
84LEAF(_restore_fp)
85 fpu_restore_single a0, t1 # clobbers t1
86 jr ra
87 END(_restore_fp)
88
89/*
90 * Load the FPU with signalling NANS. This bit pattern we're using has
91 * the property that no matter whether considered as single or as double
92 * precision represents signaling NANS.
93 *
94 * The value to initialize fcr31 to comes in $a0.
95 */
96
97 .set push
98 SET_HARDFLOAT
99
100LEAF(_init_fpu)
101 mfc0 t0, CP0_STATUS
102 li t1, ST0_CU1
103 or t0, t1
104 mtc0 t0, CP0_STATUS
105
106 ctc1 a0, fcr31
107
108 li t0, -1
109
110 mtc1 t0, $f0
111 mtc1 t0, $f1
112 mtc1 t0, $f2
113 mtc1 t0, $f3
114 mtc1 t0, $f4
115 mtc1 t0, $f5
116 mtc1 t0, $f6
117 mtc1 t0, $f7
118 mtc1 t0, $f8
119 mtc1 t0, $f9
120 mtc1 t0, $f10
121 mtc1 t0, $f11
122 mtc1 t0, $f12
123 mtc1 t0, $f13
124 mtc1 t0, $f14
125 mtc1 t0, $f15
126 mtc1 t0, $f16
127 mtc1 t0, $f17
128 mtc1 t0, $f18
129 mtc1 t0, $f19
130 mtc1 t0, $f20
131 mtc1 t0, $f21
132 mtc1 t0, $f22
133 mtc1 t0, $f23
134 mtc1 t0, $f24
135 mtc1 t0, $f25
136 mtc1 t0, $f26
137 mtc1 t0, $f27
138 mtc1 t0, $f28
139 mtc1 t0, $f29
140 mtc1 t0, $f30
141 mtc1 t0, $f31
142 jr ra
143 END(_init_fpu)
144
145 .set pop
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 56d86b09c917..0a83b1708b3c 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -15,6 +15,7 @@
15#include <asm/asm.h> 15#include <asm/asm.h>
16#include <asm/asmmacro.h> 16#include <asm/asmmacro.h>
17#include <asm/errno.h> 17#include <asm/errno.h>
18#include <asm/export.h>
18#include <asm/fpregdef.h> 19#include <asm/fpregdef.h>
19#include <asm/mipsregs.h> 20#include <asm/mipsregs.h>
20#include <asm/asm-offsets.h> 21#include <asm/asm-offsets.h>
@@ -34,6 +35,201 @@
34 .previous 35 .previous
35 .endm 36 .endm
36 37
38/*
39 * Save a thread's fp context.
40 */
41LEAF(_save_fp)
42EXPORT_SYMBOL(_save_fp)
43#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
44 defined(CONFIG_CPU_MIPS32_R6)
45 mfc0 t0, CP0_STATUS
46#endif
47 fpu_save_double a0 t0 t1 # clobbers t1
48 jr ra
49 END(_save_fp)
50
51/*
52 * Restore a thread's fp context.
53 */
54LEAF(_restore_fp)
55#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
56 defined(CONFIG_CPU_MIPS32_R6)
57 mfc0 t0, CP0_STATUS
58#endif
59 fpu_restore_double a0 t0 t1 # clobbers t1
60 jr ra
61 END(_restore_fp)
62
63#ifdef CONFIG_CPU_HAS_MSA
64
65/*
66 * Save a thread's MSA vector context.
67 */
68LEAF(_save_msa)
69EXPORT_SYMBOL(_save_msa)
70 msa_save_all a0
71 jr ra
72 END(_save_msa)
73
74/*
75 * Restore a thread's MSA vector context.
76 */
77LEAF(_restore_msa)
78 msa_restore_all a0
79 jr ra
80 END(_restore_msa)
81
82LEAF(_init_msa_upper)
83 msa_init_all_upper
84 jr ra
85 END(_init_msa_upper)
86
87#endif
88
89/*
90 * Load the FPU with signalling NANS. This bit pattern we're using has
91 * the property that no matter whether considered as single or as double
92 * precision represents signaling NANS.
93 *
94 * The value to initialize fcr31 to comes in $a0.
95 */
96
97 .set push
98 SET_HARDFLOAT
99
100LEAF(_init_fpu)
101 mfc0 t0, CP0_STATUS
102 li t1, ST0_CU1
103 or t0, t1
104 mtc0 t0, CP0_STATUS
105 enable_fpu_hazard
106
107 ctc1 a0, fcr31
108
109 li t1, -1 # SNaN
110
111#ifdef CONFIG_64BIT
112 sll t0, t0, 5
113 bgez t0, 1f # 16 / 32 register mode?
114
115 dmtc1 t1, $f1
116 dmtc1 t1, $f3
117 dmtc1 t1, $f5
118 dmtc1 t1, $f7
119 dmtc1 t1, $f9
120 dmtc1 t1, $f11
121 dmtc1 t1, $f13
122 dmtc1 t1, $f15
123 dmtc1 t1, $f17
124 dmtc1 t1, $f19
125 dmtc1 t1, $f21
126 dmtc1 t1, $f23
127 dmtc1 t1, $f25
128 dmtc1 t1, $f27
129 dmtc1 t1, $f29
130 dmtc1 t1, $f31
1311:
132#endif
133
134#ifdef CONFIG_CPU_MIPS32
135 mtc1 t1, $f0
136 mtc1 t1, $f1
137 mtc1 t1, $f2
138 mtc1 t1, $f3
139 mtc1 t1, $f4
140 mtc1 t1, $f5
141 mtc1 t1, $f6
142 mtc1 t1, $f7
143 mtc1 t1, $f8
144 mtc1 t1, $f9
145 mtc1 t1, $f10
146 mtc1 t1, $f11
147 mtc1 t1, $f12
148 mtc1 t1, $f13
149 mtc1 t1, $f14
150 mtc1 t1, $f15
151 mtc1 t1, $f16
152 mtc1 t1, $f17
153 mtc1 t1, $f18
154 mtc1 t1, $f19
155 mtc1 t1, $f20
156 mtc1 t1, $f21
157 mtc1 t1, $f22
158 mtc1 t1, $f23
159 mtc1 t1, $f24
160 mtc1 t1, $f25
161 mtc1 t1, $f26
162 mtc1 t1, $f27
163 mtc1 t1, $f28
164 mtc1 t1, $f29
165 mtc1 t1, $f30
166 mtc1 t1, $f31
167
168#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6)
169 .set push
170 .set MIPS_ISA_LEVEL_RAW
171 .set fp=64
172 sll t0, t0, 5 # is Status.FR set?
173 bgez t0, 1f # no: skip setting upper 32b
174
175 mthc1 t1, $f0
176 mthc1 t1, $f1
177 mthc1 t1, $f2
178 mthc1 t1, $f3
179 mthc1 t1, $f4
180 mthc1 t1, $f5
181 mthc1 t1, $f6
182 mthc1 t1, $f7
183 mthc1 t1, $f8
184 mthc1 t1, $f9
185 mthc1 t1, $f10
186 mthc1 t1, $f11
187 mthc1 t1, $f12
188 mthc1 t1, $f13
189 mthc1 t1, $f14
190 mthc1 t1, $f15
191 mthc1 t1, $f16
192 mthc1 t1, $f17
193 mthc1 t1, $f18
194 mthc1 t1, $f19
195 mthc1 t1, $f20
196 mthc1 t1, $f21
197 mthc1 t1, $f22
198 mthc1 t1, $f23
199 mthc1 t1, $f24
200 mthc1 t1, $f25
201 mthc1 t1, $f26
202 mthc1 t1, $f27
203 mthc1 t1, $f28
204 mthc1 t1, $f29
205 mthc1 t1, $f30
206 mthc1 t1, $f31
2071: .set pop
208#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */
209#else
210 .set MIPS_ISA_ARCH_LEVEL_RAW
211 dmtc1 t1, $f0
212 dmtc1 t1, $f2
213 dmtc1 t1, $f4
214 dmtc1 t1, $f6
215 dmtc1 t1, $f8
216 dmtc1 t1, $f10
217 dmtc1 t1, $f12
218 dmtc1 t1, $f14
219 dmtc1 t1, $f16
220 dmtc1 t1, $f18
221 dmtc1 t1, $f20
222 dmtc1 t1, $f22
223 dmtc1 t1, $f24
224 dmtc1 t1, $f26
225 dmtc1 t1, $f28
226 dmtc1 t1, $f30
227#endif
228 jr ra
229 END(_init_fpu)
230
231 .set pop /* SET_HARDFLOAT */
232
37 .set noreorder 233 .set noreorder
38 234
39/** 235/**
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 7b386d54fd65..17cf9341c1cf 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -12,8 +12,6 @@
12 */ 12 */
13#include <asm/asm.h> 13#include <asm/asm.h>
14#include <asm/cachectl.h> 14#include <asm/cachectl.h>
15#include <asm/export.h>
16#include <asm/fpregdef.h>
17#include <asm/mipsregs.h> 15#include <asm/mipsregs.h>
18#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
19#include <asm/regdef.h> 17#include <asm/regdef.h>
@@ -22,10 +20,6 @@
22 20
23#include <asm/asmmacro.h> 21#include <asm/asmmacro.h>
24 22
25/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
26#undef fp
27
28#ifndef USE_ALTERNATE_RESUME_IMPL
29/* 23/*
30 * task_struct *resume(task_struct *prev, task_struct *next, 24 * task_struct *resume(task_struct *prev, task_struct *next,
31 * struct thread_info *next_ti) 25 * struct thread_info *next_ti)
@@ -63,200 +57,3 @@
63 move v0, a0 57 move v0, a0
64 jr ra 58 jr ra
65 END(resume) 59 END(resume)
66
67#endif /* USE_ALTERNATE_RESUME_IMPL */
68
69/*
70 * Save a thread's fp context.
71 */
72LEAF(_save_fp)
73EXPORT_SYMBOL(_save_fp)
74#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
75 defined(CONFIG_CPU_MIPS32_R6)
76 mfc0 t0, CP0_STATUS
77#endif
78 fpu_save_double a0 t0 t1 # clobbers t1
79 jr ra
80 END(_save_fp)
81
82/*
83 * Restore a thread's fp context.
84 */
85LEAF(_restore_fp)
86#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
87 defined(CONFIG_CPU_MIPS32_R6)
88 mfc0 t0, CP0_STATUS
89#endif
90 fpu_restore_double a0 t0 t1 # clobbers t1
91 jr ra
92 END(_restore_fp)
93
94#ifdef CONFIG_CPU_HAS_MSA
95
96/*
97 * Save a thread's MSA vector context.
98 */
99LEAF(_save_msa)
100EXPORT_SYMBOL(_save_msa)
101 msa_save_all a0
102 jr ra
103 END(_save_msa)
104
105/*
106 * Restore a thread's MSA vector context.
107 */
108LEAF(_restore_msa)
109 msa_restore_all a0
110 jr ra
111 END(_restore_msa)
112
113LEAF(_init_msa_upper)
114 msa_init_all_upper
115 jr ra
116 END(_init_msa_upper)
117
118#endif
119
120/*
121 * Load the FPU with signalling NANS. This bit pattern we're using has
122 * the property that no matter whether considered as single or as double
123 * precision represents signaling NANS.
124 *
125 * The value to initialize fcr31 to comes in $a0.
126 */
127
128 .set push
129 SET_HARDFLOAT
130
131LEAF(_init_fpu)
132 mfc0 t0, CP0_STATUS
133 li t1, ST0_CU1
134 or t0, t1
135 mtc0 t0, CP0_STATUS
136 enable_fpu_hazard
137
138 ctc1 a0, fcr31
139
140 li t1, -1 # SNaN
141
142#ifdef CONFIG_64BIT
143 sll t0, t0, 5
144 bgez t0, 1f # 16 / 32 register mode?
145
146 dmtc1 t1, $f1
147 dmtc1 t1, $f3
148 dmtc1 t1, $f5
149 dmtc1 t1, $f7
150 dmtc1 t1, $f9
151 dmtc1 t1, $f11
152 dmtc1 t1, $f13
153 dmtc1 t1, $f15
154 dmtc1 t1, $f17
155 dmtc1 t1, $f19
156 dmtc1 t1, $f21
157 dmtc1 t1, $f23
158 dmtc1 t1, $f25
159 dmtc1 t1, $f27
160 dmtc1 t1, $f29
161 dmtc1 t1, $f31
1621:
163#endif
164
165#ifdef CONFIG_CPU_MIPS32
166 mtc1 t1, $f0
167 mtc1 t1, $f1
168 mtc1 t1, $f2
169 mtc1 t1, $f3
170 mtc1 t1, $f4
171 mtc1 t1, $f5
172 mtc1 t1, $f6
173 mtc1 t1, $f7
174 mtc1 t1, $f8
175 mtc1 t1, $f9
176 mtc1 t1, $f10
177 mtc1 t1, $f11
178 mtc1 t1, $f12
179 mtc1 t1, $f13
180 mtc1 t1, $f14
181 mtc1 t1, $f15
182 mtc1 t1, $f16
183 mtc1 t1, $f17
184 mtc1 t1, $f18
185 mtc1 t1, $f19
186 mtc1 t1, $f20
187 mtc1 t1, $f21
188 mtc1 t1, $f22
189 mtc1 t1, $f23
190 mtc1 t1, $f24
191 mtc1 t1, $f25
192 mtc1 t1, $f26
193 mtc1 t1, $f27
194 mtc1 t1, $f28
195 mtc1 t1, $f29
196 mtc1 t1, $f30
197 mtc1 t1, $f31
198
199#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6)
200 .set push
201 .set MIPS_ISA_LEVEL_RAW
202 .set fp=64
203 sll t0, t0, 5 # is Status.FR set?
204 bgez t0, 1f # no: skip setting upper 32b
205
206 mthc1 t1, $f0
207 mthc1 t1, $f1
208 mthc1 t1, $f2
209 mthc1 t1, $f3
210 mthc1 t1, $f4
211 mthc1 t1, $f5
212 mthc1 t1, $f6
213 mthc1 t1, $f7
214 mthc1 t1, $f8
215 mthc1 t1, $f9
216 mthc1 t1, $f10
217 mthc1 t1, $f11
218 mthc1 t1, $f12
219 mthc1 t1, $f13
220 mthc1 t1, $f14
221 mthc1 t1, $f15
222 mthc1 t1, $f16
223 mthc1 t1, $f17
224 mthc1 t1, $f18
225 mthc1 t1, $f19
226 mthc1 t1, $f20
227 mthc1 t1, $f21
228 mthc1 t1, $f22
229 mthc1 t1, $f23
230 mthc1 t1, $f24
231 mthc1 t1, $f25
232 mthc1 t1, $f26
233 mthc1 t1, $f27
234 mthc1 t1, $f28
235 mthc1 t1, $f29
236 mthc1 t1, $f30
237 mthc1 t1, $f31
2381: .set pop
239#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */
240#else
241 .set MIPS_ISA_ARCH_LEVEL_RAW
242 dmtc1 t1, $f0
243 dmtc1 t1, $f2
244 dmtc1 t1, $f4
245 dmtc1 t1, $f6
246 dmtc1 t1, $f8
247 dmtc1 t1, $f10
248 dmtc1 t1, $f12
249 dmtc1 t1, $f14
250 dmtc1 t1, $f16
251 dmtc1 t1, $f18
252 dmtc1 t1, $f20
253 dmtc1 t1, $f22
254 dmtc1 t1, $f24
255 dmtc1 t1, $f26
256 dmtc1 t1, $f28
257 dmtc1 t1, $f30
258#endif
259 jr ra
260 END(_init_fpu)
261
262 .set pop /* SET_HARDFLOAT */
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
deleted file mode 100644
index 9cc7bfab3419..000000000000
--- a/arch/mips/kernel/r6000_fpu.S
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * r6000_fpu.S: Save/restore floating point context for signal handlers.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1996 by Ralf Baechle
9 *
10 * Multi-arch abstraction and asm macros for easier reading:
11 * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
12 */
13#include <asm/asm.h>
14#include <asm/fpregdef.h>
15#include <asm/mipsregs.h>
16#include <asm/asm-offsets.h>
17#include <asm/regdef.h>
18
19 .set noreorder
20 .set mips2
21 .set push
22 SET_HARDFLOAT
23
24/**
25 * _save_fp_context() - save FP context from the FPU
26 * @a0 - pointer to fpregs field of sigcontext
27 * @a1 - pointer to fpc_csr field of sigcontext
28 *
29 * Save FP context, including the 32 FP data registers and the FP
30 * control & status register, from the FPU to signal context.
31 */
32 LEAF(_save_fp_context)
33 mfc0 t0,CP0_STATUS
34 sll t0,t0,2
35 bgez t0,1f
36 nop
37
38 cfc1 t1,fcr31
39 /* Store the 16 double precision registers */
40 sdc1 $f0,0(a0)
41 sdc1 $f2,16(a0)
42 sdc1 $f4,32(a0)
43 sdc1 $f6,48(a0)
44 sdc1 $f8,64(a0)
45 sdc1 $f10,80(a0)
46 sdc1 $f12,96(a0)
47 sdc1 $f14,112(a0)
48 sdc1 $f16,128(a0)
49 sdc1 $f18,144(a0)
50 sdc1 $f20,160(a0)
51 sdc1 $f22,176(a0)
52 sdc1 $f24,192(a0)
53 sdc1 $f26,208(a0)
54 sdc1 $f28,224(a0)
55 sdc1 $f30,240(a0)
56 jr ra
57 sw t0,(a1)
581: jr ra
59 nop
60 END(_save_fp_context)
61
62/**
63 * _restore_fp_context() - restore FP context to the FPU
64 * @a0 - pointer to fpregs field of sigcontext
65 * @a1 - pointer to fpc_csr field of sigcontext
66 *
67 * Restore FP context, including the 32 FP data registers and the FP
68 * control & status register, from signal context to the FPU.
69 */
70 LEAF(_restore_fp_context)
71 mfc0 t0,CP0_STATUS
72 sll t0,t0,2
73
74 bgez t0,1f
75 lw t0,(a1)
76 /* Restore the 16 double precision registers */
77 ldc1 $f0,0(a0)
78 ldc1 $f2,16(a0)
79 ldc1 $f4,32(a0)
80 ldc1 $f6,48(a0)
81 ldc1 $f8,64(a0)
82 ldc1 $f10,80(a0)
83 ldc1 $f12,96(a0)
84 ldc1 $f14,112(a0)
85 ldc1 $f16,128(a0)
86 ldc1 $f18,144(a0)
87 ldc1 $f20,160(a0)
88 ldc1 $f22,176(a0)
89 ldc1 $f24,192(a0)
90 ldc1 $f26,208(a0)
91 ldc1 $f28,224(a0)
92 ldc1 $f30,240(a0)
93 jr ra
94 ctc1 t0,fcr31
951: jr ra
96 nop
97 END(_restore_fp_context)
98
99 .set pop /* SET_HARDFLOAT */
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 1b070a76fcdd..406072e26752 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -179,7 +179,7 @@ static void bmips_prepare_cpus(unsigned int max_cpus)
179/* 179/*
180 * Tell the hardware to boot CPUx - runs on CPU0 180 * Tell the hardware to boot CPUx - runs on CPU0
181 */ 181 */
182static void bmips_boot_secondary(int cpu, struct task_struct *idle) 182static int bmips_boot_secondary(int cpu, struct task_struct *idle)
183{ 183{
184 bmips_smp_boot_sp = __KSTK_TOS(idle); 184 bmips_smp_boot_sp = __KSTK_TOS(idle);
185 bmips_smp_boot_gp = (unsigned long)task_thread_info(idle); 185 bmips_smp_boot_gp = (unsigned long)task_thread_info(idle);
@@ -231,6 +231,8 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
231 } 231 }
232 cpumask_set_cpu(cpu, &bmips_booted_mask); 232 cpumask_set_cpu(cpu, &bmips_booted_mask);
233 } 233 }
234
235 return 0;
234} 236}
235 237
236/* 238/*
@@ -245,7 +247,7 @@ static void bmips_init_secondary(void)
245 break; 247 break;
246 case CPU_BMIPS5000: 248 case CPU_BMIPS5000:
247 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); 249 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
248 current_cpu_data.core = (read_c0_brcm_config() >> 25) & 3; 250 cpu_set_core(&current_cpu_data, (read_c0_brcm_config() >> 25) & 3);
249 break; 251 break;
250 } 252 }
251} 253}
@@ -409,7 +411,7 @@ void __ref play_dead(void)
409 411
410#endif /* CONFIG_HOTPLUG_CPU */ 412#endif /* CONFIG_HOTPLUG_CPU */
411 413
412struct plat_smp_ops bmips43xx_smp_ops = { 414const struct plat_smp_ops bmips43xx_smp_ops = {
413 .smp_setup = bmips_smp_setup, 415 .smp_setup = bmips_smp_setup,
414 .prepare_cpus = bmips_prepare_cpus, 416 .prepare_cpus = bmips_prepare_cpus,
415 .boot_secondary = bmips_boot_secondary, 417 .boot_secondary = bmips_boot_secondary,
@@ -423,7 +425,7 @@ struct plat_smp_ops bmips43xx_smp_ops = {
423#endif 425#endif
424}; 426};
425 427
426struct plat_smp_ops bmips5000_smp_ops = { 428const struct plat_smp_ops bmips5000_smp_ops = {
427 .smp_setup = bmips_smp_setup, 429 .smp_setup = bmips_smp_setup,
428 .prepare_cpus = bmips_prepare_cpus, 430 .prepare_cpus = bmips_prepare_cpus,
429 .boot_secondary = bmips_boot_secondary, 431 .boot_secondary = bmips_boot_secondary,
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index 76923349b4fe..05295a4909f1 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -24,7 +24,6 @@
24#include <linux/cpumask.h> 24#include <linux/cpumask.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/compiler.h> 26#include <linux/compiler.h>
27#include <linux/irqchip/mips-gic.h>
28 27
29#include <linux/atomic.h> 28#include <linux/atomic.h>
30#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
@@ -78,7 +77,7 @@ static void cmp_smp_finish(void)
78 * __KSTK_TOS(idle) is apparently the stack pointer 77 * __KSTK_TOS(idle) is apparently the stack pointer
79 * (unsigned long)idle->thread_info the gp 78 * (unsigned long)idle->thread_info the gp
80 */ 79 */
81static void cmp_boot_secondary(int cpu, struct task_struct *idle) 80static int cmp_boot_secondary(int cpu, struct task_struct *idle)
82{ 81{
83 struct thread_info *gp = task_thread_info(idle); 82 struct thread_info *gp = task_thread_info(idle);
84 unsigned long sp = __KSTK_TOS(idle); 83 unsigned long sp = __KSTK_TOS(idle);
@@ -95,6 +94,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle)
95#endif 94#endif
96 95
97 amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0); 96 amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0);
97 return 0;
98} 98}
99 99
100/* 100/*
@@ -148,7 +148,7 @@ void __init cmp_prepare_cpus(unsigned int max_cpus)
148 148
149} 149}
150 150
151struct plat_smp_ops cmp_smp_ops = { 151const struct plat_smp_ops cmp_smp_ops = {
152 .send_ipi_single = mips_smp_send_ipi_single, 152 .send_ipi_single = mips_smp_send_ipi_single,
153 .send_ipi_mask = mips_smp_send_ipi_mask, 153 .send_ipi_mask = mips_smp_send_ipi_mask,
154 .init_secondary = cmp_init_secondary, 154 .init_secondary = cmp_init_secondary,
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index f832e99ad4c3..0063122c85da 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -11,7 +11,6 @@
11#include <linux/cpu.h> 11#include <linux/cpu.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/irqchip/mips-gic.h>
15#include <linux/sched/task_stack.h> 14#include <linux/sched/task_stack.h>
16#include <linux/sched/hotplug.h> 15#include <linux/sched/hotplug.h>
17#include <linux/slab.h> 16#include <linux/slab.h>
@@ -19,8 +18,7 @@
19#include <linux/types.h> 18#include <linux/types.h>
20 19
21#include <asm/bcache.h> 20#include <asm/bcache.h>
22#include <asm/mips-cm.h> 21#include <asm/mips-cps.h>
23#include <asm/mips-cpc.h>
24#include <asm/mips_mt.h> 22#include <asm/mips_mt.h>
25#include <asm/mipsregs.h> 23#include <asm/mipsregs.h>
26#include <asm/pm-cps.h> 24#include <asm/pm-cps.h>
@@ -41,55 +39,58 @@ static int __init setup_nothreads(char *s)
41} 39}
42early_param("nothreads", setup_nothreads); 40early_param("nothreads", setup_nothreads);
43 41
44static unsigned core_vpe_count(unsigned core) 42static unsigned core_vpe_count(unsigned int cluster, unsigned core)
45{ 43{
46 unsigned cfg;
47
48 if (threads_disabled) 44 if (threads_disabled)
49 return 1; 45 return 1;
50 46
51 if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt) 47 return mips_cps_numvps(cluster, core);
52 && (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp))
53 return 1;
54
55 mips_cm_lock_other(core, 0);
56 cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK;
57 mips_cm_unlock_other();
58 return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
59} 48}
60 49
61static void __init cps_smp_setup(void) 50static void __init cps_smp_setup(void)
62{ 51{
63 unsigned int ncores, nvpes, core_vpes; 52 unsigned int nclusters, ncores, nvpes, core_vpes;
64 unsigned long core_entry; 53 unsigned long core_entry;
65 int c, v; 54 int cl, c, v;
66 55
67 /* Detect & record VPE topology */ 56 /* Detect & record VPE topology */
68 ncores = mips_cm_numcores(); 57 nvpes = 0;
58 nclusters = mips_cps_numclusters();
69 pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE"); 59 pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE");
70 for (c = nvpes = 0; c < ncores; c++) { 60 for (cl = 0; cl < nclusters; cl++) {
71 core_vpes = core_vpe_count(c); 61 if (cl > 0)
72 pr_cont("%c%u", c ? ',' : '{', core_vpes); 62 pr_cont(",");
73 63 pr_cont("{");
74 /* Use the number of VPEs in core 0 for smp_num_siblings */ 64
75 if (!c) 65 ncores = mips_cps_numcores(cl);
76 smp_num_siblings = core_vpes; 66 for (c = 0; c < ncores; c++) {
77 67 core_vpes = core_vpe_count(cl, c);
78 for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) { 68
79 cpu_data[nvpes + v].core = c; 69 if (c > 0)
80#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) 70 pr_cont(",");
81 cpu_data[nvpes + v].vpe_id = v; 71 pr_cont("%u", core_vpes);
82#endif 72
73 /* Use the number of VPEs in cluster 0 core 0 for smp_num_siblings */
74 if (!cl && !c)
75 smp_num_siblings = core_vpes;
76
77 for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
78 cpu_set_cluster(&cpu_data[nvpes + v], cl);
79 cpu_set_core(&cpu_data[nvpes + v], c);
80 cpu_set_vpe_id(&cpu_data[nvpes + v], v);
81 }
82
83 nvpes += core_vpes;
83 } 84 }
84 85
85 nvpes += core_vpes; 86 pr_cont("}");
86 } 87 }
87 pr_cont("} total %u\n", nvpes); 88 pr_cont(" total %u\n", nvpes);
88 89
89 /* Indicate present CPUs (CPU being synonymous with VPE) */ 90 /* Indicate present CPUs (CPU being synonymous with VPE) */
90 for (v = 0; v < min_t(unsigned, nvpes, NR_CPUS); v++) { 91 for (v = 0; v < min_t(unsigned, nvpes, NR_CPUS); v++) {
91 set_cpu_possible(v, true); 92 set_cpu_possible(v, cpu_cluster(&cpu_data[v]) == 0);
92 set_cpu_present(v, true); 93 set_cpu_present(v, cpu_cluster(&cpu_data[v]) == 0);
93 __cpu_number_map[v] = v; 94 __cpu_number_map[v] = v;
94 __cpu_logical_map[v] = v; 95 __cpu_logical_map[v] = v;
95 } 96 }
@@ -121,7 +122,7 @@ static void __init cps_smp_setup(void)
121static void __init cps_prepare_cpus(unsigned int max_cpus) 122static void __init cps_prepare_cpus(unsigned int max_cpus)
122{ 123{
123 unsigned ncores, core_vpes, c, cca; 124 unsigned ncores, core_vpes, c, cca;
124 bool cca_unsuitable; 125 bool cca_unsuitable, cores_limited;
125 u32 *entry_code; 126 u32 *entry_code;
126 127
127 mips_mt_set_cpuoptions(); 128 mips_mt_set_cpuoptions();
@@ -141,19 +142,22 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
141 } 142 }
142 143
143 /* Warn the user if the CCA prevents multi-core */ 144 /* Warn the user if the CCA prevents multi-core */
144 ncores = mips_cm_numcores(); 145 cores_limited = false;
145 if ((cca_unsuitable || cpu_has_dc_aliases) && ncores > 1) { 146 if (cca_unsuitable || cpu_has_dc_aliases) {
147 for_each_present_cpu(c) {
148 if (cpus_are_siblings(smp_processor_id(), c))
149 continue;
150
151 set_cpu_present(c, false);
152 cores_limited = true;
153 }
154 }
155 if (cores_limited)
146 pr_warn("Using only one core due to %s%s%s\n", 156 pr_warn("Using only one core due to %s%s%s\n",
147 cca_unsuitable ? "unsuitable CCA" : "", 157 cca_unsuitable ? "unsuitable CCA" : "",
148 (cca_unsuitable && cpu_has_dc_aliases) ? " & " : "", 158 (cca_unsuitable && cpu_has_dc_aliases) ? " & " : "",
149 cpu_has_dc_aliases ? "dcache aliasing" : ""); 159 cpu_has_dc_aliases ? "dcache aliasing" : "");
150 160
151 for_each_present_cpu(c) {
152 if (cpu_data[c].core)
153 set_cpu_present(c, false);
154 }
155 }
156
157 /* 161 /*
158 * Patch the start of mips_cps_core_entry to provide: 162 * Patch the start of mips_cps_core_entry to provide:
159 * 163 *
@@ -168,6 +172,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
168 __sync(); 172 __sync();
169 173
170 /* Allocate core boot configuration structs */ 174 /* Allocate core boot configuration structs */
175 ncores = mips_cps_numcores(0);
171 mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg), 176 mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg),
172 GFP_KERNEL); 177 GFP_KERNEL);
173 if (!mips_cps_core_bootcfg) { 178 if (!mips_cps_core_bootcfg) {
@@ -177,7 +182,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
177 182
178 /* Allocate VPE boot configuration structs */ 183 /* Allocate VPE boot configuration structs */
179 for (c = 0; c < ncores; c++) { 184 for (c = 0; c < ncores; c++) {
180 core_vpes = core_vpe_count(c); 185 core_vpes = core_vpe_count(0, c);
181 mips_cps_core_bootcfg[c].vpe_config = kcalloc(core_vpes, 186 mips_cps_core_bootcfg[c].vpe_config = kcalloc(core_vpes,
182 sizeof(*mips_cps_core_bootcfg[c].vpe_config), 187 sizeof(*mips_cps_core_bootcfg[c].vpe_config),
183 GFP_KERNEL); 188 GFP_KERNEL);
@@ -189,7 +194,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
189 } 194 }
190 195
191 /* Mark this CPU as booted */ 196 /* Mark this CPU as booted */
192 atomic_set(&mips_cps_core_bootcfg[current_cpu_data.core].vpe_mask, 197 atomic_set(&mips_cps_core_bootcfg[cpu_core(&current_cpu_data)].vpe_mask,
193 1 << cpu_vpe_id(&current_cpu_data)); 198 1 << cpu_vpe_id(&current_cpu_data));
194 199
195 return; 200 return;
@@ -212,11 +217,11 @@ err_out:
212 217
213static void boot_core(unsigned int core, unsigned int vpe_id) 218static void boot_core(unsigned int core, unsigned int vpe_id)
214{ 219{
215 u32 access, stat, seq_state; 220 u32 stat, seq_state;
216 unsigned timeout; 221 unsigned timeout;
217 222
218 /* Select the appropriate core */ 223 /* Select the appropriate core */
219 mips_cm_lock_other(core, 0); 224 mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
220 225
221 /* Set its reset vector */ 226 /* Set its reset vector */
222 write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry)); 227 write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry));
@@ -225,12 +230,10 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
225 write_gcr_co_coherence(0); 230 write_gcr_co_coherence(0);
226 231
227 /* Start it with the legacy memory map and exception base */ 232 /* Start it with the legacy memory map and exception base */
228 write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB); 233 write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
229 234
230 /* Ensure the core can access the GCRs */ 235 /* Ensure the core can access the GCRs */
231 access = read_gcr_access(); 236 set_gcr_access(1 << core);
232 access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);
233 write_gcr_access(access);
234 237
235 if (mips_cpc_present()) { 238 if (mips_cpc_present()) {
236 /* Reset the core */ 239 /* Reset the core */
@@ -253,7 +256,8 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
253 timeout = 100; 256 timeout = 100;
254 while (true) { 257 while (true) {
255 stat = read_cpc_co_stat_conf(); 258 stat = read_cpc_co_stat_conf();
256 seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE_MSK; 259 seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE;
260 seq_state >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE);
257 261
258 /* U6 == coherent execution, ie. the core is up */ 262 /* U6 == coherent execution, ie. the core is up */
259 if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6) 263 if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6)
@@ -285,15 +289,15 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
285 289
286static void remote_vpe_boot(void *dummy) 290static void remote_vpe_boot(void *dummy)
287{ 291{
288 unsigned core = current_cpu_data.core; 292 unsigned core = cpu_core(&current_cpu_data);
289 struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; 293 struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
290 294
291 mips_cps_boot_vpes(core_cfg, cpu_vpe_id(&current_cpu_data)); 295 mips_cps_boot_vpes(core_cfg, cpu_vpe_id(&current_cpu_data));
292} 296}
293 297
294static void cps_boot_secondary(int cpu, struct task_struct *idle) 298static int cps_boot_secondary(int cpu, struct task_struct *idle)
295{ 299{
296 unsigned core = cpu_data[cpu].core; 300 unsigned core = cpu_core(&cpu_data[cpu]);
297 unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); 301 unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]);
298 struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; 302 struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
299 struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id]; 303 struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id];
@@ -301,6 +305,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
301 unsigned int remote; 305 unsigned int remote;
302 int err; 306 int err;
303 307
308 /* We don't yet support booting CPUs in other clusters */
309 if (cpu_cluster(&cpu_data[cpu]) != cpu_cluster(&current_cpu_data))
310 return -ENOSYS;
311
304 vpe_cfg->pc = (unsigned long)&smp_bootstrap; 312 vpe_cfg->pc = (unsigned long)&smp_bootstrap;
305 vpe_cfg->sp = __KSTK_TOS(idle); 313 vpe_cfg->sp = __KSTK_TOS(idle);
306 vpe_cfg->gp = (unsigned long)task_thread_info(idle); 314 vpe_cfg->gp = (unsigned long)task_thread_info(idle);
@@ -316,16 +324,16 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
316 } 324 }
317 325
318 if (cpu_has_vp) { 326 if (cpu_has_vp) {
319 mips_cm_lock_other(core, vpe_id); 327 mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
320 core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry); 328 core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry);
321 write_gcr_co_reset_base(core_entry); 329 write_gcr_co_reset_base(core_entry);
322 mips_cm_unlock_other(); 330 mips_cm_unlock_other();
323 } 331 }
324 332
325 if (core != current_cpu_data.core) { 333 if (!cpus_are_siblings(cpu, smp_processor_id())) {
326 /* Boot a VPE on another powered up core */ 334 /* Boot a VPE on another powered up core */
327 for (remote = 0; remote < NR_CPUS; remote++) { 335 for (remote = 0; remote < NR_CPUS; remote++) {
328 if (cpu_data[remote].core != core) 336 if (!cpus_are_siblings(cpu, remote))
329 continue; 337 continue;
330 if (cpu_online(remote)) 338 if (cpu_online(remote))
331 break; 339 break;
@@ -349,6 +357,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
349 mips_cps_boot_vpes(core_cfg, vpe_id); 357 mips_cps_boot_vpes(core_cfg, vpe_id);
350out: 358out:
351 preempt_enable(); 359 preempt_enable();
360 return 0;
352} 361}
353 362
354static void cps_init_secondary(void) 363static void cps_init_secondary(void)
@@ -358,7 +367,7 @@ static void cps_init_secondary(void)
358 dmt(); 367 dmt();
359 368
360 if (mips_cm_revision() >= CM_REV_CM3) { 369 if (mips_cm_revision() >= CM_REV_CM3) {
361 unsigned ident = gic_read_local_vp_id(); 370 unsigned int ident = read_gic_vl_ident();
362 371
363 /* 372 /*
364 * Ensure that our calculation of the VP ID matches up with 373 * Ensure that our calculation of the VP ID matches up with
@@ -402,7 +411,7 @@ static int cps_cpu_disable(void)
402 if (!cps_pm_support_state(CPS_PM_POWER_GATED)) 411 if (!cps_pm_support_state(CPS_PM_POWER_GATED))
403 return -EINVAL; 412 return -EINVAL;
404 413
405 core_cfg = &mips_cps_core_bootcfg[current_cpu_data.core]; 414 core_cfg = &mips_cps_core_bootcfg[cpu_core(&current_cpu_data)];
406 atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask); 415 atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask);
407 smp_mb__after_atomic(); 416 smp_mb__after_atomic();
408 set_cpu_online(cpu, false); 417 set_cpu_online(cpu, false);
@@ -424,15 +433,17 @@ void play_dead(void)
424 local_irq_disable(); 433 local_irq_disable();
425 idle_task_exit(); 434 idle_task_exit();
426 cpu = smp_processor_id(); 435 cpu = smp_processor_id();
427 core = cpu_data[cpu].core; 436 core = cpu_core(&cpu_data[cpu]);
428 cpu_death = CPU_DEATH_POWER; 437 cpu_death = CPU_DEATH_POWER;
429 438
430 pr_debug("CPU%d going offline\n", cpu); 439 pr_debug("CPU%d going offline\n", cpu);
431 440
432 if (cpu_has_mipsmt || cpu_has_vp) { 441 if (cpu_has_mipsmt || cpu_has_vp) {
442 core = cpu_core(&cpu_data[cpu]);
443
433 /* Look for another online VPE within the core */ 444 /* Look for another online VPE within the core */
434 for_each_online_cpu(cpu_death_sibling) { 445 for_each_online_cpu(cpu_death_sibling) {
435 if (cpu_data[cpu_death_sibling].core != core) 446 if (!cpus_are_siblings(cpu, cpu_death_sibling))
436 continue; 447 continue;
437 448
438 /* 449 /*
@@ -488,7 +499,7 @@ static void wait_for_sibling_halt(void *ptr_cpu)
488 499
489static void cps_cpu_die(unsigned int cpu) 500static void cps_cpu_die(unsigned int cpu)
490{ 501{
491 unsigned core = cpu_data[cpu].core; 502 unsigned core = cpu_core(&cpu_data[cpu]);
492 unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]); 503 unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]);
493 ktime_t fail_time; 504 ktime_t fail_time;
494 unsigned stat; 505 unsigned stat;
@@ -519,10 +530,11 @@ static void cps_cpu_die(unsigned int cpu)
519 */ 530 */
520 fail_time = ktime_add_ms(ktime_get(), 2000); 531 fail_time = ktime_add_ms(ktime_get(), 2000);
521 do { 532 do {
522 mips_cm_lock_other(core, 0); 533 mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
523 mips_cpc_lock_other(core); 534 mips_cpc_lock_other(core);
524 stat = read_cpc_co_stat_conf(); 535 stat = read_cpc_co_stat_conf();
525 stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK; 536 stat &= CPC_Cx_STAT_CONF_SEQSTATE;
537 stat >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE);
526 mips_cpc_unlock_other(); 538 mips_cpc_unlock_other();
527 mips_cm_unlock_other(); 539 mips_cm_unlock_other();
528 540
@@ -544,7 +556,7 @@ static void cps_cpu_die(unsigned int cpu)
544 */ 556 */
545 if (WARN(ktime_after(ktime_get(), fail_time), 557 if (WARN(ktime_after(ktime_get(), fail_time),
546 "CPU%u hasn't powered down, seq. state %u\n", 558 "CPU%u hasn't powered down, seq. state %u\n",
547 cpu, stat >> CPC_Cx_STAT_CONF_SEQSTATE_SHF)) 559 cpu, stat))
548 break; 560 break;
549 } while (1); 561 } while (1);
550 562
@@ -562,7 +574,7 @@ static void cps_cpu_die(unsigned int cpu)
562 panic("Failed to call remote sibling CPU\n"); 574 panic("Failed to call remote sibling CPU\n");
563 } else if (cpu_has_vp) { 575 } else if (cpu_has_vp) {
564 do { 576 do {
565 mips_cm_lock_other(core, vpe_id); 577 mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
566 stat = read_cpc_co_vp_running(); 578 stat = read_cpc_co_vp_running();
567 mips_cm_unlock_other(); 579 mips_cm_unlock_other();
568 } while (stat & (1 << vpe_id)); 580 } while (stat & (1 << vpe_id));
@@ -571,7 +583,7 @@ static void cps_cpu_die(unsigned int cpu)
571 583
572#endif /* CONFIG_HOTPLUG_CPU */ 584#endif /* CONFIG_HOTPLUG_CPU */
573 585
574static struct plat_smp_ops cps_smp_ops = { 586static const struct plat_smp_ops cps_smp_ops = {
575 .smp_setup = cps_smp_setup, 587 .smp_setup = cps_smp_setup,
576 .prepare_cpus = cps_prepare_cpus, 588 .prepare_cpus = cps_prepare_cpus,
577 .boot_secondary = cps_boot_secondary, 589 .boot_secondary = cps_boot_secondary,
@@ -587,7 +599,7 @@ static struct plat_smp_ops cps_smp_ops = {
587 599
588bool mips_cps_smp_in_use(void) 600bool mips_cps_smp_in_use(void)
589{ 601{
590 extern struct plat_smp_ops *mp_ops; 602 extern const struct plat_smp_ops *mp_ops;
591 return mp_ops == &cps_smp_ops; 603 return mp_ops == &cps_smp_ops;
592} 604}
593 605
@@ -599,7 +611,7 @@ int register_cps_smp_ops(void)
599 } 611 }
600 612
601 /* check we have a GIC - we need one for IPIs */ 613 /* check we have a GIC - we need one for IPIs */
602 if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX_MSK)) { 614 if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX)) {
603 pr_warn("MIPS CPS SMP unable to proceed without a GIC\n"); 615 pr_warn("MIPS CPS SMP unable to proceed without a GIC\n");
604 return -ENODEV; 616 return -ENODEV;
605 } 617 }
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index ed6b4df583ea..94ab3276b48c 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -21,7 +21,6 @@
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/cpumask.h> 22#include <linux/cpumask.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/irqchip/mips-gic.h>
25#include <linux/compiler.h> 24#include <linux/compiler.h>
26#include <linux/sched/task_stack.h> 25#include <linux/sched/task_stack.h>
27#include <linux/smp.h> 26#include <linux/smp.h>
@@ -36,6 +35,7 @@
36#include <asm/mipsregs.h> 35#include <asm/mipsregs.h>
37#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
38#include <asm/mips_mt.h> 37#include <asm/mips_mt.h>
38#include <asm/mips-cps.h>
39 39
40static void __init smvp_copy_vpe_config(void) 40static void __init smvp_copy_vpe_config(void)
41{ 41{
@@ -83,7 +83,7 @@ static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
83 if (tc != 0) 83 if (tc != 0)
84 smvp_copy_vpe_config(); 84 smvp_copy_vpe_config();
85 85
86 cpu_data[ncpu].vpe_id = tc; 86 cpu_set_vpe_id(&cpu_data[ncpu], tc);
87 87
88 return ncpu; 88 return ncpu;
89} 89}
@@ -118,14 +118,12 @@ static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
118 118
119static void vsmp_init_secondary(void) 119static void vsmp_init_secondary(void)
120{ 120{
121#ifdef CONFIG_MIPS_GIC
122 /* This is Malta specific: IPI,performance and timer interrupts */ 121 /* This is Malta specific: IPI,performance and timer interrupts */
123 if (gic_present) 122 if (mips_gic_present())
124 change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | 123 change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 |
125 STATUSF_IP4 | STATUSF_IP5 | 124 STATUSF_IP4 | STATUSF_IP5 |
126 STATUSF_IP6 | STATUSF_IP7); 125 STATUSF_IP6 | STATUSF_IP7);
127 else 126 else
128#endif
129 change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 | 127 change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
130 STATUSF_IP6 | STATUSF_IP7); 128 STATUSF_IP6 | STATUSF_IP7);
131} 129}
@@ -152,7 +150,7 @@ static void vsmp_smp_finish(void)
152 * (unsigned long)idle->thread_info the gp 150 * (unsigned long)idle->thread_info the gp
153 * assumes a 1:1 mapping of TC => VPE 151 * assumes a 1:1 mapping of TC => VPE
154 */ 152 */
155static void vsmp_boot_secondary(int cpu, struct task_struct *idle) 153static int vsmp_boot_secondary(int cpu, struct task_struct *idle)
156{ 154{
157 struct thread_info *gp = task_thread_info(idle); 155 struct thread_info *gp = task_thread_info(idle);
158 dvpe(); 156 dvpe();
@@ -184,6 +182,8 @@ static void vsmp_boot_secondary(int cpu, struct task_struct *idle)
184 clear_c0_mvpcontrol(MVPCONTROL_VPC); 182 clear_c0_mvpcontrol(MVPCONTROL_VPC);
185 183
186 evpe(EVPE_ENABLE); 184 evpe(EVPE_ENABLE);
185
186 return 0;
187} 187}
188 188
189/* 189/*
@@ -239,7 +239,7 @@ static void __init vsmp_prepare_cpus(unsigned int max_cpus)
239 mips_mt_set_cpuoptions(); 239 mips_mt_set_cpuoptions();
240} 240}
241 241
242struct plat_smp_ops vsmp_smp_ops = { 242const struct plat_smp_ops vsmp_smp_ops = {
243 .send_ipi_single = mips_smp_send_ipi_single, 243 .send_ipi_single = mips_smp_send_ipi_single,
244 .send_ipi_mask = mips_smp_send_ipi_mask, 244 .send_ipi_mask = mips_smp_send_ipi_mask,
245 .init_secondary = vsmp_init_secondary, 245 .init_secondary = vsmp_init_secondary,
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c
index 17878d71ef2b..525d3196f793 100644
--- a/arch/mips/kernel/smp-up.c
+++ b/arch/mips/kernel/smp-up.c
@@ -39,8 +39,9 @@ static void up_smp_finish(void)
39/* 39/*
40 * Firmware CPU startup hook 40 * Firmware CPU startup hook
41 */ 41 */
42static void up_boot_secondary(int cpu, struct task_struct *idle) 42static int up_boot_secondary(int cpu, struct task_struct *idle)
43{ 43{
44 return 0;
44} 45}
45 46
46static void __init up_smp_setup(void) 47static void __init up_smp_setup(void)
@@ -63,7 +64,7 @@ static void up_cpu_die(unsigned int cpu)
63} 64}
64#endif 65#endif
65 66
66struct plat_smp_ops up_smp_ops = { 67const struct plat_smp_ops up_smp_ops = {
67 .send_ipi_single = up_send_ipi_single, 68 .send_ipi_single = up_send_ipi_single,
68 .send_ipi_mask = up_send_ipi_mask, 69 .send_ipi_mask = up_send_ipi_mask,
69 .init_secondary = up_init_secondary, 70 .init_secondary = up_init_secondary,
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index c7cbddfcdc3b..bbe19b64def5 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -96,8 +96,7 @@ static inline void set_cpu_sibling_map(int cpu)
96 96
97 if (smp_num_siblings > 1) { 97 if (smp_num_siblings > 1) {
98 for_each_cpu(i, &cpu_sibling_setup_map) { 98 for_each_cpu(i, &cpu_sibling_setup_map) {
99 if (cpu_data[cpu].package == cpu_data[i].package && 99 if (cpus_are_siblings(cpu, i)) {
100 cpu_data[cpu].core == cpu_data[i].core) {
101 cpumask_set_cpu(i, &cpu_sibling_map[cpu]); 100 cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
102 cpumask_set_cpu(cpu, &cpu_sibling_map[i]); 101 cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
103 } 102 }
@@ -134,8 +133,7 @@ void calculate_cpu_foreign_map(void)
134 for_each_online_cpu(i) { 133 for_each_online_cpu(i) {
135 core_present = 0; 134 core_present = 0;
136 for_each_cpu(k, &temp_foreign_map) 135 for_each_cpu(k, &temp_foreign_map)
137 if (cpu_data[i].package == cpu_data[k].package && 136 if (cpus_are_siblings(i, k))
138 cpu_data[i].core == cpu_data[k].core)
139 core_present = 1; 137 core_present = 1;
140 if (!core_present) 138 if (!core_present)
141 cpumask_set_cpu(i, &temp_foreign_map); 139 cpumask_set_cpu(i, &temp_foreign_map);
@@ -146,10 +144,10 @@ void calculate_cpu_foreign_map(void)
146 &temp_foreign_map, &cpu_sibling_map[i]); 144 &temp_foreign_map, &cpu_sibling_map[i]);
147} 145}
148 146
149struct plat_smp_ops *mp_ops; 147const struct plat_smp_ops *mp_ops;
150EXPORT_SYMBOL(mp_ops); 148EXPORT_SYMBOL(mp_ops);
151 149
152void register_smp_ops(struct plat_smp_ops *ops) 150void register_smp_ops(const struct plat_smp_ops *ops)
153{ 151{
154 if (mp_ops) 152 if (mp_ops)
155 printk(KERN_WARNING "Overriding previously set SMP ops\n"); 153 printk(KERN_WARNING "Overriding previously set SMP ops\n");
@@ -186,13 +184,13 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
186 184
187 if (mips_cpc_present()) { 185 if (mips_cpc_present()) {
188 for_each_cpu(cpu, mask) { 186 for_each_cpu(cpu, mask) {
189 core = cpu_data[cpu].core; 187 if (cpus_are_siblings(cpu, smp_processor_id()))
190
191 if (core == current_cpu_data.core)
192 continue; 188 continue;
193 189
190 core = cpu_core(&cpu_data[cpu]);
191
194 while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { 192 while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
195 mips_cm_lock_other(core, 0); 193 mips_cm_lock_other_cpu(cpu, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
196 mips_cpc_lock_other(core); 194 mips_cpc_lock_other(core);
197 write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); 195 write_cpc_co_cmd(CPC_Cx_CMD_PWRUP);
198 mips_cpc_unlock_other(); 196 mips_cpc_unlock_other();
@@ -441,7 +439,11 @@ void smp_prepare_boot_cpu(void)
441 439
442int __cpu_up(unsigned int cpu, struct task_struct *tidle) 440int __cpu_up(unsigned int cpu, struct task_struct *tidle)
443{ 441{
444 mp_ops->boot_secondary(cpu, tidle); 442 int err;
443
444 err = mp_ops->boot_secondary(cpu, tidle);
445 if (err)
446 return err;
445 447
446 /* 448 /*
447 * We must check for timeout here, as the CPU will not be marked 449 * We must check for timeout here, as the CPU will not be marked
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index c036157fb891..a6ebc8135112 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -72,20 +72,6 @@ EXPORT_SYMBOL(perf_irq);
72unsigned int mips_hpt_frequency; 72unsigned int mips_hpt_frequency;
73EXPORT_SYMBOL_GPL(mips_hpt_frequency); 73EXPORT_SYMBOL_GPL(mips_hpt_frequency);
74 74
75/*
76 * This function exists in order to cause an error due to a duplicate
77 * definition if platform code should have its own implementation. The hook
78 * to use instead is plat_time_init. plat_time_init does not receive the
79 * irqaction pointer argument anymore. This is because any function which
80 * initializes an interrupt timer now takes care of its own request_irq rsp.
81 * setup_irq calls and each clock_event_device should use its own
82 * struct irqrequest.
83 */
84void __init plat_timer_setup(void)
85{
86 BUG();
87}
88
89static __init int cpu_has_mfc0_count_bug(void) 75static __init int cpu_has_mfc0_count_bug(void)
90{ 76{
91 switch (current_cpu_type()) { 77 switch (current_cpu_type()) {
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2bf414993347..5669d3b8bd38 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -50,9 +50,8 @@
50#include <asm/fpu.h> 50#include <asm/fpu.h>
51#include <asm/fpu_emulator.h> 51#include <asm/fpu_emulator.h>
52#include <asm/idle.h> 52#include <asm/idle.h>
53#include <asm/mips-cm.h> 53#include <asm/mips-cps.h>
54#include <asm/mips-r2-to-r6-emul.h> 54#include <asm/mips-r2-to-r6-emul.h>
55#include <asm/mips-cm.h>
56#include <asm/mipsregs.h> 55#include <asm/mipsregs.h>
57#include <asm/mipsmtregs.h> 56#include <asm/mipsmtregs.h>
58#include <asm/module.h> 57#include <asm/module.h>
@@ -734,8 +733,7 @@ void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
734 si.si_code = FPE_FLTUND; 733 si.si_code = FPE_FLTUND;
735 else if (fcr31 & FPU_CSR_INE_X) 734 else if (fcr31 & FPU_CSR_INE_X)
736 si.si_code = FPE_FLTRES; 735 si.si_code = FPE_FLTRES;
737 else 736
738 return; /* Broken hardware? */
739 force_sig_info(SIGFPE, &si, tsk); 737 force_sig_info(SIGFPE, &si, tsk);
740} 738}
741 739
@@ -1673,7 +1671,7 @@ static inline void parity_protection_init(void)
1673 /* Probe L2 ECC support */ 1671 /* Probe L2 ECC support */
1674 gcr_ectl = read_gcr_err_control(); 1672 gcr_ectl = read_gcr_err_control();
1675 1673
1676 if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK) || 1674 if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT) ||
1677 !(cp0_ectl & ERRCTL_PE)) { 1675 !(cp0_ectl & ERRCTL_PE)) {
1678 /* 1676 /*
1679 * One of L1 or L2 ECC checking isn't supported, 1677 * One of L1 or L2 ECC checking isn't supported,
@@ -1693,12 +1691,12 @@ static inline void parity_protection_init(void)
1693 1691
1694 /* Configure L2 ECC checking */ 1692 /* Configure L2 ECC checking */
1695 if (l2parity) 1693 if (l2parity)
1696 gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; 1694 gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN;
1697 else 1695 else
1698 gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; 1696 gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN;
1699 write_gcr_err_control(gcr_ectl); 1697 write_gcr_err_control(gcr_ectl);
1700 gcr_ectl = read_gcr_err_control(); 1698 gcr_ectl = read_gcr_err_control();
1701 gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; 1699 gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN;
1702 WARN_ON(!!gcr_ectl != l2parity); 1700 WARN_ON(!!gcr_ectl != l2parity);
1703 1701
1704 pr_info("Cache parity protection %sabled\n", 1702 pr_info("Cache parity protection %sabled\n",
@@ -2428,21 +2426,6 @@ void __init trap_init(void)
2428 set_except_vector(EXCCODE_TR, handle_tr); 2426 set_except_vector(EXCCODE_TR, handle_tr);
2429 set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe); 2427 set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
2430 2428
2431 if (current_cpu_type() == CPU_R6000 ||
2432 current_cpu_type() == CPU_R6000A) {
2433 /*
2434 * The R6000 is the only R-series CPU that features a machine
2435 * check exception (similar to the R4000 cache error) and
2436 * unaligned ldc1/sdc1 exception. The handlers have not been
2437 * written yet. Well, anyway there is no R6000 machine on the
2438 * current list of targets for Linux/MIPS.
2439 * (Duh, crap, there is someone with a triple R6k machine)
2440 */
2441 //set_except_vector(14, handle_mc);
2442 //set_except_vector(15, handle_ndc);
2443 }
2444
2445
2446 if (board_nmi_handler_setup) 2429 if (board_nmi_handler_setup)
2447 board_nmi_handler_setup(); 2430 board_nmi_handler_setup();
2448 2431
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 5eaf2578ac04..2d0b912f9e3e 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -1378,7 +1378,7 @@ sigill:
1378const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; 1378const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
1379 1379
1380/* Recode table from 16-bit STORE register notation to 32-bit GPR. */ 1380/* Recode table from 16-bit STORE register notation to 32-bit GPR. */
1381const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; 1381static const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
1382 1382
1383static void emulate_load_store_microMIPS(struct pt_regs *regs, 1383static void emulate_load_store_microMIPS(struct pt_regs *regs,
1384 void __user *addr) 1384 void __user *addr)
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 093517e85a6c..019035d7225c 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -13,13 +13,13 @@
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/ioport.h> 15#include <linux/ioport.h>
16#include <linux/irqchip/mips-gic.h>
17#include <linux/mm.h> 16#include <linux/mm.h>
18#include <linux/sched.h> 17#include <linux/sched.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include <linux/timekeeper_internal.h> 19#include <linux/timekeeper_internal.h>
21 20
22#include <asm/abi.h> 21#include <asm/abi.h>
22#include <asm/mips-cps.h>
23#include <asm/vdso.h> 23#include <asm/vdso.h>
24 24
25/* Kernel-provided data used by the VDSO. */ 25/* Kernel-provided data used by the VDSO. */
@@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
99{ 99{
100 struct mips_vdso_image *image = current->thread.abi->vdso; 100 struct mips_vdso_image *image = current->thread.abi->vdso;
101 struct mm_struct *mm = current->mm; 101 struct mm_struct *mm = current->mm;
102 unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr; 102 unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn;
103 struct vm_area_struct *vma; 103 struct vm_area_struct *vma;
104 struct resource gic_res;
105 int ret; 104 int ret;
106 105
107 if (down_write_killable(&mm->mmap_sem)) 106 if (down_write_killable(&mm->mmap_sem))
@@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
125 * only map a page even though the total area is 64K, as we only need 124 * only map a page even though the total area is 64K, as we only need
126 * the counter registers at the start. 125 * the counter registers at the start.
127 */ 126 */
128 gic_size = gic_present ? PAGE_SIZE : 0; 127 gic_size = mips_gic_present() ? PAGE_SIZE : 0;
129 vvar_size = gic_size + PAGE_SIZE; 128 vvar_size = gic_size + PAGE_SIZE;
130 size = vvar_size + image->size; 129 size = vvar_size + image->size;
131 130
@@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
148 147
149 /* Map GIC user page. */ 148 /* Map GIC user page. */
150 if (gic_size) { 149 if (gic_size) {
151 ret = gic_get_usm_range(&gic_res); 150 gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >> PAGE_SHIFT;
152 if (ret)
153 goto out;
154 151
155 ret = io_remap_pfn_range(vma, base, 152 ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
156 gic_res.start >> PAGE_SHIFT,
157 gic_size,
158 pgprot_noncached(PAGE_READONLY)); 153 pgprot_noncached(PAGE_READONLY));
159 if (ret) 154 if (ret)
160 goto out; 155 goto out;
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index 177769dbb0e8..35bc69b78268 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -17,6 +17,8 @@ config SOC_XWAY
17 bool "XWAY" 17 bool "XWAY"
18 select SOC_TYPE_XWAY 18 select SOC_TYPE_XWAY
19 select HW_HAS_PCI 19 select HW_HAS_PCI
20 select MFD_SYSCON
21 select MFD_CORE
20 22
21config SOC_FALCON 23config SOC_FALCON
22 bool "FALCON" 24 bool "FALCON"
diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c
index 7a535d72f541..058b85578cf7 100644
--- a/arch/mips/lantiq/falcon/reset.c
+++ b/arch/mips/lantiq/falcon/reset.c
@@ -15,27 +15,14 @@
15 15
16#include <lantiq_soc.h> 16#include <lantiq_soc.h>
17 17
18/* CPU0 Reset Source Register */ 18/*
19#define SYS1_CPU0RS 0x0040 19 * Dummy implementation. Used to allow platform code to find out what
20/* reset cause mask */ 20 * source was booted from
21#define CPU0RS_MASK 0x0003 21 */
22/* CPU0 Boot Mode Register */
23#define SYS1_BM 0x00a0
24/* boot mode mask */
25#define BM_MASK 0x0005
26
27/* allow platform code to find out what surce we booted from */
28unsigned char ltq_boot_select(void) 22unsigned char ltq_boot_select(void)
29{ 23{
30 return ltq_sys1_r32(SYS1_BM) & BM_MASK; 24 return BS_SPI;
31}
32
33/* allow the watchdog driver to find out what the boot reason was */
34int ltq_reset_cause(void)
35{
36 return ltq_sys1_r32(SYS1_CPU0RS) & CPU0RS_MASK;
37} 25}
38EXPORT_SYMBOL_GPL(ltq_reset_cause);
39 26
40#define BOOT_REG_BASE (KSEG1 | 0x1F200000) 27#define BOOT_REG_BASE (KSEG1 | 0x1F200000)
41#define BOOT_PW1_REG (BOOT_REG_BASE | 0x20) 28#define BOOT_PW1_REG (BOOT_REG_BASE | 0x20)
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 33728b7af426..f0bc3312ed11 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -61,10 +61,6 @@
61/* we have a cascade of 8 irqs */ 61/* we have a cascade of 8 irqs */
62#define MIPS_CPU_IRQ_CASCADE 8 62#define MIPS_CPU_IRQ_CASCADE 8
63 63
64#ifdef CONFIG_MIPS_MT_SMP
65int gic_present;
66#endif
67
68static int exin_avail; 64static int exin_avail;
69static u32 ltq_eiu_irq[MAX_EIU]; 65static u32 ltq_eiu_irq[MAX_EIU];
70static void __iomem *ltq_icu_membase[MAX_IM]; 66static void __iomem *ltq_icu_membase[MAX_IM];
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index 96773bed8a8a..9ff7ccde9de0 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -117,7 +117,7 @@ void __init prom_init(void)
117 117
118int __init plat_of_setup(void) 118int __init plat_of_setup(void)
119{ 119{
120 return __dt_register_buses(soc_info.compatible, "simple-bus"); 120 return of_platform_default_populate(NULL, NULL, NULL);
121} 121}
122 122
123arch_initcall(plat_of_setup); 123arch_initcall(plat_of_setup);
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index a2edc538f477..fbb0747c70b7 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,5 +1,3 @@
1obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o 1obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o
2 2
3obj-y += vmmc.o 3obj-y += vmmc.o
4
5obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
deleted file mode 100644
index 83fd65d76e81..000000000000
--- a/arch/mips/lantiq/xway/reset.c
+++ /dev/null
@@ -1,387 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <john@phrozen.org>
7 * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
8 */
9
10#include <linux/init.h>
11#include <linux/io.h>
12#include <linux/ioport.h>
13#include <linux/pm.h>
14#include <linux/export.h>
15#include <linux/delay.h>
16#include <linux/of_address.h>
17#include <linux/of_platform.h>
18#include <linux/reset-controller.h>
19
20#include <asm/reboot.h>
21
22#include <lantiq_soc.h>
23
24#include "../prom.h"
25
26/* reset request register */
27#define RCU_RST_REQ 0x0010
28/* reset status register */
29#define RCU_RST_STAT 0x0014
30/* vr9 gphy registers */
31#define RCU_GFS_ADD0_XRX200 0x0020
32#define RCU_GFS_ADD1_XRX200 0x0068
33/* xRX300 gphy registers */
34#define RCU_GFS_ADD0_XRX300 0x0020
35#define RCU_GFS_ADD1_XRX300 0x0058
36#define RCU_GFS_ADD2_XRX300 0x00AC
37/* xRX330 gphy registers */
38#define RCU_GFS_ADD0_XRX330 0x0020
39#define RCU_GFS_ADD1_XRX330 0x0058
40#define RCU_GFS_ADD2_XRX330 0x00AC
41#define RCU_GFS_ADD3_XRX330 0x0264
42
43/* xbar BE flag */
44#define RCU_AHB_ENDIAN 0x004C
45#define RCU_VR9_BE_AHB1S 0x00000008
46
47/* reboot bit */
48#define RCU_RD_GPHY0_XRX200 BIT(31)
49#define RCU_RD_SRST BIT(30)
50#define RCU_RD_GPHY1_XRX200 BIT(29)
51/* xRX300 bits */
52#define RCU_RD_GPHY0_XRX300 BIT(31)
53#define RCU_RD_GPHY1_XRX300 BIT(29)
54#define RCU_RD_GPHY2_XRX300 BIT(28)
55/* xRX330 bits */
56#define RCU_RD_GPHY0_XRX330 BIT(31)
57#define RCU_RD_GPHY1_XRX330 BIT(29)
58#define RCU_RD_GPHY2_XRX330 BIT(28)
59#define RCU_RD_GPHY3_XRX330 BIT(10)
60
61/* reset cause */
62#define RCU_STAT_SHIFT 26
63/* boot selection */
64#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7)
65#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10))
66
67/* dwc2 USB configuration registers */
68#define RCU_USB1CFG 0x0018
69#define RCU_USB2CFG 0x0034
70
71/* USB DMA endianness bits */
72#define RCU_USBCFG_HDSEL_BIT BIT(11)
73#define RCU_USBCFG_HOST_END_BIT BIT(10)
74#define RCU_USBCFG_SLV_END_BIT BIT(9)
75
76/* USB reset bits */
77#define RCU_USBRESET 0x0010
78
79#define USBRESET_BIT BIT(4)
80
81#define RCU_USBRESET2 0x0048
82
83#define USB1RESET_BIT BIT(4)
84#define USB2RESET_BIT BIT(5)
85
86#define RCU_CFG1A 0x0038
87#define RCU_CFG1B 0x003C
88
89/* USB PMU devices */
90#define PMU_AHBM BIT(15)
91#define PMU_USB0 BIT(6)
92#define PMU_USB1 BIT(27)
93
94/* USB PHY PMU devices */
95#define PMU_USB0_P BIT(0)
96#define PMU_USB1_P BIT(26)
97
98/* remapped base addr of the reset control unit */
99static void __iomem *ltq_rcu_membase;
100static struct device_node *ltq_rcu_np;
101static DEFINE_SPINLOCK(ltq_rcu_lock);
102
103static void ltq_rcu_w32(uint32_t val, uint32_t reg_off)
104{
105 ltq_w32(val, ltq_rcu_membase + reg_off);
106}
107
108static uint32_t ltq_rcu_r32(uint32_t reg_off)
109{
110 return ltq_r32(ltq_rcu_membase + reg_off);
111}
112
113static void ltq_rcu_w32_mask(uint32_t clr, uint32_t set, uint32_t reg_off)
114{
115 unsigned long flags;
116
117 spin_lock_irqsave(&ltq_rcu_lock, flags);
118 ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off);
119 spin_unlock_irqrestore(&ltq_rcu_lock, flags);
120}
121
122/* This function is used by the watchdog driver */
123int ltq_reset_cause(void)
124{
125 u32 val = ltq_rcu_r32(RCU_RST_STAT);
126 return val >> RCU_STAT_SHIFT;
127}
128EXPORT_SYMBOL_GPL(ltq_reset_cause);
129
130/* allow platform code to find out what source we booted from */
131unsigned char ltq_boot_select(void)
132{
133 u32 val = ltq_rcu_r32(RCU_RST_STAT);
134
135 if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
136 return RCU_BOOT_SEL_XRX200(val);
137
138 return RCU_BOOT_SEL(val);
139}
140
141struct ltq_gphy_reset {
142 u32 rd;
143 u32 addr;
144};
145
146/* reset / boot a gphy */
147static struct ltq_gphy_reset xrx200_gphy[] = {
148 {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200},
149 {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200},
150};
151
152/* reset / boot a gphy */
153static struct ltq_gphy_reset xrx300_gphy[] = {
154 {RCU_RD_GPHY0_XRX300, RCU_GFS_ADD0_XRX300},
155 {RCU_RD_GPHY1_XRX300, RCU_GFS_ADD1_XRX300},
156 {RCU_RD_GPHY2_XRX300, RCU_GFS_ADD2_XRX300},
157};
158
159/* reset / boot a gphy */
160static struct ltq_gphy_reset xrx330_gphy[] = {
161 {RCU_RD_GPHY0_XRX330, RCU_GFS_ADD0_XRX330},
162 {RCU_RD_GPHY1_XRX330, RCU_GFS_ADD1_XRX330},
163 {RCU_RD_GPHY2_XRX330, RCU_GFS_ADD2_XRX330},
164 {RCU_RD_GPHY3_XRX330, RCU_GFS_ADD3_XRX330},
165};
166
167static void xrx200_gphy_boot_addr(struct ltq_gphy_reset *phy_regs,
168 dma_addr_t dev_addr)
169{
170 ltq_rcu_w32_mask(0, phy_regs->rd, RCU_RST_REQ);
171 ltq_rcu_w32(dev_addr, phy_regs->addr);
172 ltq_rcu_w32_mask(phy_regs->rd, 0, RCU_RST_REQ);
173}
174
175/* reset and boot a gphy. these phys only exist on xrx200 SoC */
176int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
177{
178 struct clk *clk;
179
180 if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) {
181 dev_err(dev, "this SoC has no GPHY\n");
182 return -EINVAL;
183 }
184
185 if (of_machine_is_compatible("lantiq,vr9")) {
186 clk = clk_get_sys("1f203000.rcu", "gphy");
187 if (IS_ERR(clk))
188 return PTR_ERR(clk);
189 clk_enable(clk);
190 }
191
192 dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr);
193
194 if (of_machine_is_compatible("lantiq,vr9")) {
195 if (id >= ARRAY_SIZE(xrx200_gphy)) {
196 dev_err(dev, "%u is an invalid gphy id\n", id);
197 return -EINVAL;
198 }
199 xrx200_gphy_boot_addr(&xrx200_gphy[id], dev_addr);
200 } else if (of_machine_is_compatible("lantiq,ar10")) {
201 if (id >= ARRAY_SIZE(xrx300_gphy)) {
202 dev_err(dev, "%u is an invalid gphy id\n", id);
203 return -EINVAL;
204 }
205 xrx200_gphy_boot_addr(&xrx300_gphy[id], dev_addr);
206 } else if (of_machine_is_compatible("lantiq,grx390")) {
207 if (id >= ARRAY_SIZE(xrx330_gphy)) {
208 dev_err(dev, "%u is an invalid gphy id\n", id);
209 return -EINVAL;
210 }
211 xrx200_gphy_boot_addr(&xrx330_gphy[id], dev_addr);
212 }
213 return 0;
214}
215
216/* reset a io domain for u micro seconds */
217void ltq_reset_once(unsigned int module, ulong u)
218{
219 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
220 udelay(u);
221 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
222}
223
224static int ltq_assert_device(struct reset_controller_dev *rcdev,
225 unsigned long id)
226{
227 u32 val;
228
229 if (id < 8)
230 return -1;
231
232 val = ltq_rcu_r32(RCU_RST_REQ);
233 val |= BIT(id);
234 ltq_rcu_w32(val, RCU_RST_REQ);
235
236 return 0;
237}
238
239static int ltq_deassert_device(struct reset_controller_dev *rcdev,
240 unsigned long id)
241{
242 u32 val;
243
244 if (id < 8)
245 return -1;
246
247 val = ltq_rcu_r32(RCU_RST_REQ);
248 val &= ~BIT(id);
249 ltq_rcu_w32(val, RCU_RST_REQ);
250
251 return 0;
252}
253
254static int ltq_reset_device(struct reset_controller_dev *rcdev,
255 unsigned long id)
256{
257 ltq_assert_device(rcdev, id);
258 return ltq_deassert_device(rcdev, id);
259}
260
261static const struct reset_control_ops reset_ops = {
262 .reset = ltq_reset_device,
263 .assert = ltq_assert_device,
264 .deassert = ltq_deassert_device,
265};
266
267static struct reset_controller_dev reset_dev = {
268 .ops = &reset_ops,
269 .owner = THIS_MODULE,
270 .nr_resets = 32,
271 .of_reset_n_cells = 1,
272};
273
274void ltq_rst_init(void)
275{
276 reset_dev.of_node = of_find_compatible_node(NULL, NULL,
277 "lantiq,xway-reset");
278 if (!reset_dev.of_node)
279 pr_err("Failed to find reset controller node");
280 else
281 reset_controller_register(&reset_dev);
282}
283
284static void ltq_machine_restart(char *command)
285{
286 u32 val = ltq_rcu_r32(RCU_RST_REQ);
287
288 if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
289 val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200;
290
291 val |= RCU_RD_SRST;
292
293 local_irq_disable();
294 ltq_rcu_w32(val, RCU_RST_REQ);
295 unreachable();
296}
297
298static void ltq_machine_halt(void)
299{
300 local_irq_disable();
301 unreachable();
302}
303
304static void ltq_machine_power_off(void)
305{
306 local_irq_disable();
307 unreachable();
308}
309
310static void ltq_usb_init(void)
311{
312 /* Power for USB cores 1 & 2 */
313 ltq_pmu_enable(PMU_AHBM);
314 ltq_pmu_enable(PMU_USB0);
315 ltq_pmu_enable(PMU_USB1);
316
317 ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A);
318 ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B);
319
320 /* Enable USB PHY power for cores 1 & 2 */
321 ltq_pmu_enable(PMU_USB0_P);
322 ltq_pmu_enable(PMU_USB1_P);
323
324 /* Configure cores to host mode */
325 ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
326 RCU_USB1CFG);
327 ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
328 RCU_USB2CFG);
329
330 /* Select DMA endianness (Host-endian: big-endian) */
331 ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
332 | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
333 ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT)
334 | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
335
336 /* Hard reset USB state machines */
337 ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET);
338 udelay(50 * 1000);
339 ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET);
340
341 /* Soft reset USB state machines */
342 ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
343 | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2);
344 udelay(50 * 1000);
345 ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
346 & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2);
347}
348
349static int __init mips_reboot_setup(void)
350{
351 struct resource res;
352
353 ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
354 if (!ltq_rcu_np)
355 ltq_rcu_np = of_find_compatible_node(NULL, NULL,
356 "lantiq,rcu-xrx200");
357
358 /* check if all the reset register range is available */
359 if (!ltq_rcu_np)
360 panic("Failed to load reset resources from devicetree");
361
362 if (of_address_to_resource(ltq_rcu_np, 0, &res))
363 panic("Failed to get rcu memory range");
364
365 if (!request_mem_region(res.start, resource_size(&res), res.name))
366 pr_err("Failed to request rcu memory");
367
368 ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res));
369 if (!ltq_rcu_membase)
370 panic("Failed to remap core memory");
371
372 if (of_machine_is_compatible("lantiq,ar9") ||
373 of_machine_is_compatible("lantiq,vr9"))
374 ltq_usb_init();
375
376 if (of_machine_is_compatible("lantiq,vr9"))
377 ltq_rcu_w32(ltq_rcu_r32(RCU_AHB_ENDIAN) | RCU_VR9_BE_AHB1S,
378 RCU_AHB_ENDIAN);
379
380 _machine_restart = ltq_machine_restart;
381 _machine_halt = ltq_machine_halt;
382 pm_power_off = ltq_machine_power_off;
383
384 return 0;
385}
386
387arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index 95bec460b651..7611c3013793 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -145,15 +145,7 @@ static u32 pmu_clk_cr_b[] = {
145#define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y)) 145#define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y))
146#define pmu_r32(x) ltq_r32(pmu_membase + (x)) 146#define pmu_r32(x) ltq_r32(pmu_membase + (x))
147 147
148#define XBAR_ALWAYS_LAST 0x430
149#define XBAR_FPI_BURST_EN BIT(1)
150#define XBAR_AHB_BURST_EN BIT(2)
151
152#define xbar_w32(x, y) ltq_w32((x), ltq_xbar_membase + (y))
153#define xbar_r32(x) ltq_r32(ltq_xbar_membase + (x))
154
155static void __iomem *pmu_membase; 148static void __iomem *pmu_membase;
156static void __iomem *ltq_xbar_membase;
157void __iomem *ltq_cgu_membase; 149void __iomem *ltq_cgu_membase;
158void __iomem *ltq_ebu_membase; 150void __iomem *ltq_ebu_membase;
159 151
@@ -293,16 +285,6 @@ static void pci_ext_disable(struct clk *clk)
293 ltq_cgu_w32((1 << 31) | (1 << 30), pcicr); 285 ltq_cgu_w32((1 << 31) | (1 << 30), pcicr);
294} 286}
295 287
296static void xbar_fpi_burst_disable(void)
297{
298 u32 reg;
299
300 /* bit 1 as 1 --burst; bit 1 as 0 -- single */
301 reg = xbar_r32(XBAR_ALWAYS_LAST);
302 reg &= ~XBAR_FPI_BURST_EN;
303 xbar_w32(reg, XBAR_ALWAYS_LAST);
304}
305
306/* enable a clockout source */ 288/* enable a clockout source */
307static int clkout_enable(struct clk *clk) 289static int clkout_enable(struct clk *clk)
308{ 290{
@@ -459,26 +441,6 @@ void __init ltq_soc_init(void)
459 if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase) 441 if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase)
460 panic("Failed to remap core resources"); 442 panic("Failed to remap core resources");
461 443
462 if (of_machine_is_compatible("lantiq,vr9")) {
463 struct resource res_xbar;
464 struct device_node *np_xbar =
465 of_find_compatible_node(NULL, NULL,
466 "lantiq,xbar-xway");
467
468 if (!np_xbar)
469 panic("Failed to load xbar nodes from devicetree");
470 if (of_address_to_resource(np_xbar, 0, &res_xbar))
471 panic("Failed to get xbar resources");
472 if (!request_mem_region(res_xbar.start, resource_size(&res_xbar),
473 res_xbar.name))
474 panic("Failed to get xbar resources");
475
476 ltq_xbar_membase = ioremap_nocache(res_xbar.start,
477 resource_size(&res_xbar));
478 if (!ltq_xbar_membase)
479 panic("Failed to remap xbar resources");
480 }
481
482 /* make sure to unprotect the memory region where flash is located */ 444 /* make sure to unprotect the memory region where flash is located */
483 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); 445 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
484 446
@@ -507,8 +469,8 @@ void __init ltq_soc_init(void)
507 469
508 if (of_machine_is_compatible("lantiq,grx390") || 470 if (of_machine_is_compatible("lantiq,grx390") ||
509 of_machine_is_compatible("lantiq,ar10")) { 471 of_machine_is_compatible("lantiq,ar10")) {
510 clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P); 472 clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P);
511 clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P); 473 clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P);
512 /* rc 0 */ 474 /* rc 0 */
513 clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P); 475 clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
514 clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); 476 clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
@@ -528,8 +490,8 @@ void __init ltq_soc_init(void)
528 else 490 else
529 clkdev_add_static(CLOCK_133M, CLOCK_133M, 491 clkdev_add_static(CLOCK_133M, CLOCK_133M,
530 CLOCK_133M, CLOCK_133M); 492 CLOCK_133M, CLOCK_133M);
531 clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); 493 clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
532 clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); 494 clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
533 clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE); 495 clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
534 clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY); 496 clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
535 clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY); 497 clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
@@ -538,8 +500,8 @@ void __init ltq_soc_init(void)
538 } else if (of_machine_is_compatible("lantiq,grx390")) { 500 } else if (of_machine_is_compatible("lantiq,grx390")) {
539 clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(), 501 clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(),
540 ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz()); 502 ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz());
541 clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); 503 clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
542 clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); 504 clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1);
543 /* rc 2 */ 505 /* rc 2 */
544 clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); 506 clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P);
545 clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI); 507 clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
@@ -551,22 +513,23 @@ void __init ltq_soc_init(void)
551 } else if (of_machine_is_compatible("lantiq,ar10")) { 513 } else if (of_machine_is_compatible("lantiq,ar10")) {
552 clkdev_add_static(ltq_ar10_cpu_hz(), ltq_ar10_fpi_hz(), 514 clkdev_add_static(ltq_ar10_cpu_hz(), ltq_ar10_fpi_hz(),
553 ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz()); 515 ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz());
554 clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); 516 clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
555 clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); 517 clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1);
556 clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | 518 clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH |
557 PMU_PPE_DP | PMU_PPE_TC); 519 PMU_PPE_DP | PMU_PPE_TC);
558 clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); 520 clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
559 clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY); 521 clkdev_add_pmu("1f203020.gphy", NULL, 1, 0, PMU_GPHY);
522 clkdev_add_pmu("1f203068.gphy", NULL, 1, 0, PMU_GPHY);
560 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); 523 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
561 clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE); 524 clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE);
562 clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); 525 clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
563 } else if (of_machine_is_compatible("lantiq,vr9")) { 526 } else if (of_machine_is_compatible("lantiq,vr9")) {
564 clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(), 527 clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
565 ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz()); 528 ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz());
566 clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); 529 clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
567 clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM); 530 clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM);
568 clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P); 531 clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P);
569 clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM); 532 clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM);
570 clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY); 533 clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY);
571 clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK); 534 clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK);
572 clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); 535 clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
@@ -579,17 +542,18 @@ void __init ltq_soc_init(void)
579 PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | 542 PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
580 PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | 543 PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
581 PMU_PPE_QSB | PMU_PPE_TOP); 544 PMU_PPE_QSB | PMU_PPE_TOP);
582 clkdev_add_pmu("1f203000.rcu", "gphy", 0, 0, PMU_GPHY); 545 clkdev_add_pmu("1f203020.gphy", NULL, 0, 0, PMU_GPHY);
546 clkdev_add_pmu("1f203068.gphy", NULL, 0, 0, PMU_GPHY);
583 clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); 547 clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
584 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); 548 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
585 clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); 549 clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
586 } else if (of_machine_is_compatible("lantiq,ar9")) { 550 } else if (of_machine_is_compatible("lantiq,ar9")) {
587 clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), 551 clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
588 ltq_ar9_fpi_hz(), CLOCK_250M); 552 ltq_ar9_fpi_hz(), CLOCK_250M);
589 clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); 553 clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
590 clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); 554 clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
591 clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); 555 clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P);
592 clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P); 556 clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1);
593 clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH); 557 clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
594 clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); 558 clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
595 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); 559 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
@@ -598,14 +562,11 @@ void __init ltq_soc_init(void)
598 } else { 562 } else {
599 clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), 563 clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
600 ltq_danube_fpi_hz(), ltq_danube_pp32_hz()); 564 ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
601 clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); 565 clkdev_add_pmu("1f203018.usb2-phy", "ctrl", 1, 0, PMU_USB0);
602 clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); 566 clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
603 clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); 567 clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
604 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); 568 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
605 clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); 569 clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
606 clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0); 570 clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
607 } 571 }
608
609 if (of_machine_is_compatible("lantiq,vr9"))
610 xbar_fpi_burst_disable();
611} 572}
diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c
deleted file mode 100644
index f0a0f2d431b2..000000000000
--- a/arch/mips/lantiq/xway/xrx200_phy_fw.c
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 * Lantiq XRX200 PHY Firmware Loader
3 * Author: John Crispin
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation.
8 *
9 * Copyright (C) 2012 John Crispin <john@phrozen.org>
10 */
11
12#include <linux/delay.h>
13#include <linux/dma-mapping.h>
14#include <linux/firmware.h>
15#include <linux/of_platform.h>
16
17#include <lantiq_soc.h>
18
19#define XRX200_GPHY_FW_ALIGN (16 * 1024)
20
21static dma_addr_t xway_gphy_load(struct platform_device *pdev)
22{
23 const struct firmware *fw;
24 dma_addr_t dev_addr = 0;
25 const char *fw_name;
26 void *fw_addr;
27 size_t size;
28
29 if (of_get_property(pdev->dev.of_node, "firmware1", NULL) ||
30 of_get_property(pdev->dev.of_node, "firmware2", NULL)) {
31 switch (ltq_soc_type()) {
32 case SOC_TYPE_VR9:
33 if (of_property_read_string(pdev->dev.of_node,
34 "firmware1", &fw_name)) {
35 dev_err(&pdev->dev,
36 "failed to load firmware filename\n");
37 return 0;
38 }
39 break;
40 case SOC_TYPE_VR9_2:
41 if (of_property_read_string(pdev->dev.of_node,
42 "firmware2", &fw_name)) {
43 dev_err(&pdev->dev,
44 "failed to load firmware filename\n");
45 return 0;
46 }
47 break;
48 }
49 } else if (of_property_read_string(pdev->dev.of_node,
50 "firmware", &fw_name)) {
51 dev_err(&pdev->dev, "failed to load firmware filename\n");
52 return 0;
53 }
54
55 dev_info(&pdev->dev, "requesting %s\n", fw_name);
56 if (request_firmware(&fw, fw_name, &pdev->dev)) {
57 dev_err(&pdev->dev, "failed to load firmware: %s\n", fw_name);
58 return 0;
59 }
60
61 /*
62 * GPHY cores need the firmware code in a persistent and contiguous
63 * memory area with a 16 kB boundary aligned start address
64 */
65 size = fw->size + XRX200_GPHY_FW_ALIGN;
66
67 fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL);
68 if (fw_addr) {
69 fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN);
70 dev_addr = ALIGN(dev_addr, XRX200_GPHY_FW_ALIGN);
71 memcpy(fw_addr, fw->data, fw->size);
72 } else {
73 dev_err(&pdev->dev, "failed to alloc firmware memory\n");
74 }
75
76 release_firmware(fw);
77 return dev_addr;
78}
79
80static int xway_phy_fw_probe(struct platform_device *pdev)
81{
82 dma_addr_t fw_addr;
83 struct property *pp;
84 unsigned char *phyids;
85 int i, ret = 0;
86
87 fw_addr = xway_gphy_load(pdev);
88 if (!fw_addr)
89 return -EINVAL;
90 pp = of_find_property(pdev->dev.of_node, "phys", NULL);
91 if (!pp)
92 return -ENOENT;
93 phyids = pp->value;
94 for (i = 0; i < pp->length && !ret; i++)
95 ret = xrx200_gphy_boot(&pdev->dev, phyids[i], fw_addr);
96 if (!ret)
97 mdelay(100);
98 return ret;
99}
100
101static const struct of_device_id xway_phy_match[] = {
102 { .compatible = "lantiq,phy-xrx200" },
103 {},
104};
105
106static struct platform_driver xway_phy_driver = {
107 .probe = xway_phy_fw_probe,
108 .driver = {
109 .name = "phy-xrx200",
110 .of_match_table = xway_phy_match,
111 },
112};
113builtin_platform_driver(xway_phy_driver);
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index a37fe3d1ee2f..6ab430d24575 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -6,7 +6,7 @@ lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \
6 mips-atomic.o strncpy_user.o \ 6 mips-atomic.o strncpy_user.o \
7 strnlen_user.o uncached.o 7 strnlen_user.o uncached.o
8 8
9obj-y += iomap.o 9obj-y += iomap.o iomap_copy.o
10obj-$(CONFIG_PCI) += iomap-pci.o 10obj-$(CONFIG_PCI) += iomap-pci.o
11lib-$(CONFIG_GENERIC_CSUM) := $(filter-out csum_partial.o, $(lib-y)) 11lib-$(CONFIG_GENERIC_CSUM) := $(filter-out csum_partial.o, $(lib-y))
12 12
diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c
index 2307a3cb2714..68c495ed71e3 100644
--- a/arch/mips/lib/delay.c
+++ b/arch/mips/lib/delay.c
@@ -8,6 +8,7 @@
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 * Copyright (C) 2007, 2014 Maciej W. Rozycki 9 * Copyright (C) 2007, 2014 Maciej W. Rozycki
10 */ 10 */
11#include <linux/delay.h>
11#include <linux/export.h> 12#include <linux/export.h>
12#include <linux/param.h> 13#include <linux/param.h>
13#include <linux/smp.h> 14#include <linux/smp.h>
diff --git a/arch/mips/lib/iomap_copy.c b/arch/mips/lib/iomap_copy.c
new file mode 100644
index 000000000000..368bb38267c5
--- /dev/null
+++ b/arch/mips/lib/iomap_copy.c
@@ -0,0 +1,42 @@
1/*
2 * This file is free software; you can redistribute it and/or modify
3 * it under the terms of version 2 of the GNU General Public License
4 * as published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
14 */
15
16#include <linux/export.h>
17#include <linux/io.h>
18
19/**
20 * __ioread64_copy - copy data from MMIO space, in 64-bit units
21 * @to: destination (must be 64-bit aligned)
22 * @from: source, in MMIO space (must be 64-bit aligned)
23 * @count: number of 64-bit quantities to copy
24 *
25 * Copy data from MMIO space to kernel space, in units of 32 or 64 bits at a
26 * time. Order of access is not guaranteed, nor is a memory barrier
27 * performed afterwards.
28 */
29void __ioread64_copy(void *to, const void __iomem *from, size_t count)
30{
31#ifdef CONFIG_64BIT
32 u64 *dst = to;
33 const u64 __iomem *src = from;
34 const u64 __iomem *end = src + count;
35
36 while (src < end)
37 *dst++ = __raw_readq(src++);
38#else
39 __ioread32_copy(to, from, count * 2);
40#endif
41}
42EXPORT_SYMBOL_GPL(__ioread64_copy);
diff --git a/arch/mips/loongson64/lemote-2f/clock.c b/arch/mips/loongson64/lemote-2f/clock.c
index a78fb657068c..8281334df9c8 100644
--- a/arch/mips/loongson64/lemote-2f/clock.c
+++ b/arch/mips/loongson64/lemote-2f/clock.c
@@ -80,6 +80,9 @@ EXPORT_SYMBOL(clk_disable);
80 80
81unsigned long clk_get_rate(struct clk *clk) 81unsigned long clk_get_rate(struct clk *clk)
82{ 82{
83 if (!clk)
84 return 0;
85
83 return (unsigned long)clk->rate; 86 return (unsigned long)clk->rate;
84} 87}
85EXPORT_SYMBOL(clk_get_rate); 88EXPORT_SYMBOL(clk_get_rate);
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index b7a355c3c408..8501109bb0f0 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -319,8 +319,8 @@ static void loongson3_init_secondary(void)
319 loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); 319 loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]);
320 320
321 per_cpu(cpu_state, cpu) = CPU_ONLINE; 321 per_cpu(cpu_state, cpu) = CPU_ONLINE;
322 cpu_data[cpu].core = 322 cpu_set_core(&cpu_data[cpu],
323 cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; 323 cpu_logical_map(cpu) % loongson_sysconf.cores_per_package);
324 cpu_data[cpu].package = 324 cpu_data[cpu].package =
325 cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; 325 cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
326 326
@@ -386,7 +386,8 @@ static void __init loongson3_smp_setup(void)
386 ipi_status0_regs_init(); 386 ipi_status0_regs_init();
387 ipi_en0_regs_init(); 387 ipi_en0_regs_init();
388 ipi_mailbox_buf_init(); 388 ipi_mailbox_buf_init();
389 cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package; 389 cpu_set_core(&cpu_data[0],
390 cpu_logical_map(0) % loongson_sysconf.cores_per_package);
390 cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package; 391 cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
391} 392}
392 393
@@ -399,7 +400,7 @@ static void __init loongson3_prepare_cpus(unsigned int max_cpus)
399/* 400/*
400 * Setup the PC, SP, and GP of a secondary processor and start it runing! 401 * Setup the PC, SP, and GP of a secondary processor and start it runing!
401 */ 402 */
402static void loongson3_boot_secondary(int cpu, struct task_struct *idle) 403static int loongson3_boot_secondary(int cpu, struct task_struct *idle)
403{ 404{
404 unsigned long startargs[4]; 405 unsigned long startargs[4];
405 406
@@ -422,6 +423,7 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle)
422 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8)); 423 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8));
423 loongson3_ipi_write64(startargs[0], 424 loongson3_ipi_write64(startargs[0],
424 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); 425 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
426 return 0;
425} 427}
426 428
427#ifdef CONFIG_HOTPLUG_CPU 429#ifdef CONFIG_HOTPLUG_CPU
@@ -697,7 +699,7 @@ void play_dead(void)
697 699
698static int loongson3_disable_clock(unsigned int cpu) 700static int loongson3_disable_clock(unsigned int cpu)
699{ 701{
700 uint64_t core_id = cpu_data[cpu].core; 702 uint64_t core_id = cpu_core(&cpu_data[cpu]);
701 uint64_t package_id = cpu_data[cpu].package; 703 uint64_t package_id = cpu_data[cpu].package;
702 704
703 if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { 705 if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
@@ -711,7 +713,7 @@ static int loongson3_disable_clock(unsigned int cpu)
711 713
712static int loongson3_enable_clock(unsigned int cpu) 714static int loongson3_enable_clock(unsigned int cpu)
713{ 715{
714 uint64_t core_id = cpu_data[cpu].core; 716 uint64_t core_id = cpu_core(&cpu_data[cpu]);
715 uint64_t package_id = cpu_data[cpu].package; 717 uint64_t package_id = cpu_data[cpu].package;
716 718
717 if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { 719 if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
@@ -734,7 +736,7 @@ early_initcall(register_loongson3_notifier);
734 736
735#endif 737#endif
736 738
737struct plat_smp_ops loongson3_smp_ops = { 739const struct plat_smp_ops loongson3_smp_ops = {
738 .send_ipi_single = loongson3_send_ipi_single, 740 .send_ipi_single = loongson3_send_ipi_single,
739 .send_ipi_mask = loongson3_send_ipi_mask, 741 .send_ipi_mask = loongson3_send_ipi_mask,
740 .init_secondary = loongson3_init_secondary, 742 .init_secondary = loongson3_init_secondary,
diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile
index e9bbc2a6526f..e9f10b88b695 100644
--- a/arch/mips/math-emu/Makefile
+++ b/arch/mips/math-emu/Makefile
@@ -4,9 +4,11 @@
4 4
5obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \ 5obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \
6 dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \ 6 dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \
7 dp_tint.o dp_fint.o dp_maddf.o dp_2008class.o dp_fmin.o dp_fmax.o \ 7 dp_tint.o dp_fint.o dp_rint.o dp_maddf.o dp_2008class.o dp_fmin.o \
8 dp_fmax.o \
8 sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \ 9 sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \
9 sp_tint.o sp_fint.o sp_maddf.o sp_2008class.o sp_fmin.o sp_fmax.o \ 10 sp_tint.o sp_fint.o sp_rint.o sp_maddf.o sp_2008class.o sp_fmin.o \
11 sp_fmax.o \
10 dsemul.o 12 dsemul.o
11 13
12lib-y += ieee754d.o \ 14lib-y += ieee754d.o \
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index f08a7b4facb9..192542dbd972 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -58,7 +58,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
58 mips_instruction); 58 mips_instruction);
59 59
60static int fpux_emu(struct pt_regs *, 60static int fpux_emu(struct pt_regs *,
61 struct mips_fpu_struct *, mips_instruction, void *__user *); 61 struct mips_fpu_struct *, mips_instruction, void __user **);
62 62
63/* Control registers */ 63/* Control registers */
64 64
@@ -830,12 +830,12 @@ do { \
830} while (0) 830} while (0)
831 831
832#define DIFROMREG(di, x) \ 832#define DIFROMREG(di, x) \
833 ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0)) 833 ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) ^ 1)], 0))
834 834
835#define DITOREG(di, x) \ 835#define DITOREG(di, x) \
836do { \ 836do { \
837 unsigned fpr, i; \ 837 unsigned fpr, i; \
838 fpr = (x) & ~(cop1_64bit(xcp) == 0); \ 838 fpr = (x) & ~(cop1_64bit(xcp) ^ 1); \
839 set_fpr64(&ctx->fpr[fpr], 0, di); \ 839 set_fpr64(&ctx->fpr[fpr], 0, di); \
840 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++) \ 840 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++) \
841 set_fpr64(&ctx->fpr[fpr], i, 0); \ 841 set_fpr64(&ctx->fpr[fpr], i, 0); \
@@ -973,7 +973,7 @@ static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
973 */ 973 */
974 974
975static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 975static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
976 struct mm_decoded_insn dec_insn, void *__user *fault_addr) 976 struct mm_decoded_insn dec_insn, void __user **fault_addr)
977{ 977{
978 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc; 978 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
979 unsigned int cond, cbit, bit0; 979 unsigned int cond, cbit, bit0;
@@ -1195,9 +1195,11 @@ emul:
1195 bit0 = get_fpr32(fpr, 0) & 0x1; 1195 bit0 = get_fpr32(fpr, 0) & 0x1;
1196 switch (MIPSInst_RS(ir)) { 1196 switch (MIPSInst_RS(ir)) {
1197 case bc1eqz_op: 1197 case bc1eqz_op:
1198 MIPS_FPU_EMU_INC_STATS(bc1eqz);
1198 cond = bit0 == 0; 1199 cond = bit0 == 0;
1199 break; 1200 break;
1200 case bc1nez_op: 1201 case bc1nez_op:
1202 MIPS_FPU_EMU_INC_STATS(bc1nez);
1201 cond = bit0 != 0; 1203 cond = bit0 != 0;
1202 break; 1204 break;
1203 } 1205 }
@@ -1230,6 +1232,7 @@ emul:
1230 break; 1232 break;
1231 } 1233 }
1232branch_common: 1234branch_common:
1235 MIPS_FPU_EMU_INC_STATS(branches);
1233 set_delay_slot(xcp); 1236 set_delay_slot(xcp);
1234 if (cond) { 1237 if (cond) {
1235 /* 1238 /*
@@ -1460,7 +1463,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
1460DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); 1463DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
1461 1464
1462static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 1465static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1463 mips_instruction ir, void *__user *fault_addr) 1466 mips_instruction ir, void __user **fault_addr)
1464{ 1467{
1465 unsigned rcsr = 0; /* resulting csr */ 1468 unsigned rcsr = 0; /* resulting csr */
1466 1469
@@ -1682,15 +1685,19 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1682 switch (MIPSInst_FUNC(ir)) { 1685 switch (MIPSInst_FUNC(ir)) {
1683 /* binary ops */ 1686 /* binary ops */
1684 case fadd_op: 1687 case fadd_op:
1688 MIPS_FPU_EMU_INC_STATS(add_s);
1685 handler.b = ieee754sp_add; 1689 handler.b = ieee754sp_add;
1686 goto scopbop; 1690 goto scopbop;
1687 case fsub_op: 1691 case fsub_op:
1692 MIPS_FPU_EMU_INC_STATS(sub_s);
1688 handler.b = ieee754sp_sub; 1693 handler.b = ieee754sp_sub;
1689 goto scopbop; 1694 goto scopbop;
1690 case fmul_op: 1695 case fmul_op:
1696 MIPS_FPU_EMU_INC_STATS(mul_s);
1691 handler.b = ieee754sp_mul; 1697 handler.b = ieee754sp_mul;
1692 goto scopbop; 1698 goto scopbop;
1693 case fdiv_op: 1699 case fdiv_op:
1700 MIPS_FPU_EMU_INC_STATS(div_s);
1694 handler.b = ieee754sp_div; 1701 handler.b = ieee754sp_div;
1695 goto scopbop; 1702 goto scopbop;
1696 1703
@@ -1699,6 +1706,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1699 if (!cpu_has_mips_2_3_4_5_r) 1706 if (!cpu_has_mips_2_3_4_5_r)
1700 return SIGILL; 1707 return SIGILL;
1701 1708
1709 MIPS_FPU_EMU_INC_STATS(sqrt_s);
1702 handler.u = ieee754sp_sqrt; 1710 handler.u = ieee754sp_sqrt;
1703 goto scopuop; 1711 goto scopuop;
1704 1712
@@ -1711,6 +1719,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1711 if (!cpu_has_mips_4_5_64_r2_r6) 1719 if (!cpu_has_mips_4_5_64_r2_r6)
1712 return SIGILL; 1720 return SIGILL;
1713 1721
1722 MIPS_FPU_EMU_INC_STATS(rsqrt_s);
1714 handler.u = fpemu_sp_rsqrt; 1723 handler.u = fpemu_sp_rsqrt;
1715 goto scopuop; 1724 goto scopuop;
1716 1725
@@ -1718,6 +1727,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1718 if (!cpu_has_mips_4_5_64_r2_r6) 1727 if (!cpu_has_mips_4_5_64_r2_r6)
1719 return SIGILL; 1728 return SIGILL;
1720 1729
1730 MIPS_FPU_EMU_INC_STATS(recip_s);
1721 handler.u = fpemu_sp_recip; 1731 handler.u = fpemu_sp_recip;
1722 goto scopuop; 1732 goto scopuop;
1723 1733
@@ -1754,6 +1764,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1754 if (!cpu_has_mips_r6) 1764 if (!cpu_has_mips_r6)
1755 return SIGILL; 1765 return SIGILL;
1756 1766
1767 MIPS_FPU_EMU_INC_STATS(seleqz_s);
1757 SPFROMREG(rv.s, MIPSInst_FT(ir)); 1768 SPFROMREG(rv.s, MIPSInst_FT(ir));
1758 if (rv.w & 0x1) 1769 if (rv.w & 0x1)
1759 rv.w = 0; 1770 rv.w = 0;
@@ -1765,6 +1776,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1765 if (!cpu_has_mips_r6) 1776 if (!cpu_has_mips_r6)
1766 return SIGILL; 1777 return SIGILL;
1767 1778
1779 MIPS_FPU_EMU_INC_STATS(selnez_s);
1768 SPFROMREG(rv.s, MIPSInst_FT(ir)); 1780 SPFROMREG(rv.s, MIPSInst_FT(ir));
1769 if (rv.w & 0x1) 1781 if (rv.w & 0x1)
1770 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1782 SPFROMREG(rv.s, MIPSInst_FS(ir));
@@ -1778,6 +1790,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1778 if (!cpu_has_mips_r6) 1790 if (!cpu_has_mips_r6)
1779 return SIGILL; 1791 return SIGILL;
1780 1792
1793 MIPS_FPU_EMU_INC_STATS(maddf_s);
1781 SPFROMREG(ft, MIPSInst_FT(ir)); 1794 SPFROMREG(ft, MIPSInst_FT(ir));
1782 SPFROMREG(fs, MIPSInst_FS(ir)); 1795 SPFROMREG(fs, MIPSInst_FS(ir));
1783 SPFROMREG(fd, MIPSInst_FD(ir)); 1796 SPFROMREG(fd, MIPSInst_FD(ir));
@@ -1791,6 +1804,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1791 if (!cpu_has_mips_r6) 1804 if (!cpu_has_mips_r6)
1792 return SIGILL; 1805 return SIGILL;
1793 1806
1807 MIPS_FPU_EMU_INC_STATS(msubf_s);
1794 SPFROMREG(ft, MIPSInst_FT(ir)); 1808 SPFROMREG(ft, MIPSInst_FT(ir));
1795 SPFROMREG(fs, MIPSInst_FS(ir)); 1809 SPFROMREG(fs, MIPSInst_FS(ir));
1796 SPFROMREG(fd, MIPSInst_FD(ir)); 1810 SPFROMREG(fd, MIPSInst_FD(ir));
@@ -1804,9 +1818,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1804 if (!cpu_has_mips_r6) 1818 if (!cpu_has_mips_r6)
1805 return SIGILL; 1819 return SIGILL;
1806 1820
1821 MIPS_FPU_EMU_INC_STATS(rint_s);
1807 SPFROMREG(fs, MIPSInst_FS(ir)); 1822 SPFROMREG(fs, MIPSInst_FS(ir));
1808 rv.l = ieee754sp_tlong(fs); 1823 rv.s = ieee754sp_rint(fs);
1809 rv.s = ieee754sp_flong(rv.l);
1810 goto copcsr; 1824 goto copcsr;
1811 } 1825 }
1812 1826
@@ -1816,6 +1830,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1816 if (!cpu_has_mips_r6) 1830 if (!cpu_has_mips_r6)
1817 return SIGILL; 1831 return SIGILL;
1818 1832
1833 MIPS_FPU_EMU_INC_STATS(class_s);
1819 SPFROMREG(fs, MIPSInst_FS(ir)); 1834 SPFROMREG(fs, MIPSInst_FS(ir));
1820 rv.w = ieee754sp_2008class(fs); 1835 rv.w = ieee754sp_2008class(fs);
1821 rfmt = w_fmt; 1836 rfmt = w_fmt;
@@ -1828,6 +1843,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1828 if (!cpu_has_mips_r6) 1843 if (!cpu_has_mips_r6)
1829 return SIGILL; 1844 return SIGILL;
1830 1845
1846 MIPS_FPU_EMU_INC_STATS(min_s);
1831 SPFROMREG(ft, MIPSInst_FT(ir)); 1847 SPFROMREG(ft, MIPSInst_FT(ir));
1832 SPFROMREG(fs, MIPSInst_FS(ir)); 1848 SPFROMREG(fs, MIPSInst_FS(ir));
1833 rv.s = ieee754sp_fmin(fs, ft); 1849 rv.s = ieee754sp_fmin(fs, ft);
@@ -1840,6 +1856,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1840 if (!cpu_has_mips_r6) 1856 if (!cpu_has_mips_r6)
1841 return SIGILL; 1857 return SIGILL;
1842 1858
1859 MIPS_FPU_EMU_INC_STATS(mina_s);
1843 SPFROMREG(ft, MIPSInst_FT(ir)); 1860 SPFROMREG(ft, MIPSInst_FT(ir));
1844 SPFROMREG(fs, MIPSInst_FS(ir)); 1861 SPFROMREG(fs, MIPSInst_FS(ir));
1845 rv.s = ieee754sp_fmina(fs, ft); 1862 rv.s = ieee754sp_fmina(fs, ft);
@@ -1852,6 +1869,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1852 if (!cpu_has_mips_r6) 1869 if (!cpu_has_mips_r6)
1853 return SIGILL; 1870 return SIGILL;
1854 1871
1872 MIPS_FPU_EMU_INC_STATS(max_s);
1855 SPFROMREG(ft, MIPSInst_FT(ir)); 1873 SPFROMREG(ft, MIPSInst_FT(ir));
1856 SPFROMREG(fs, MIPSInst_FS(ir)); 1874 SPFROMREG(fs, MIPSInst_FS(ir));
1857 rv.s = ieee754sp_fmax(fs, ft); 1875 rv.s = ieee754sp_fmax(fs, ft);
@@ -1864,6 +1882,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1864 if (!cpu_has_mips_r6) 1882 if (!cpu_has_mips_r6)
1865 return SIGILL; 1883 return SIGILL;
1866 1884
1885 MIPS_FPU_EMU_INC_STATS(maxa_s);
1867 SPFROMREG(ft, MIPSInst_FT(ir)); 1886 SPFROMREG(ft, MIPSInst_FT(ir));
1868 SPFROMREG(fs, MIPSInst_FS(ir)); 1887 SPFROMREG(fs, MIPSInst_FS(ir));
1869 rv.s = ieee754sp_fmaxa(fs, ft); 1888 rv.s = ieee754sp_fmaxa(fs, ft);
@@ -1871,15 +1890,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1871 } 1890 }
1872 1891
1873 case fabs_op: 1892 case fabs_op:
1893 MIPS_FPU_EMU_INC_STATS(abs_s);
1874 handler.u = ieee754sp_abs; 1894 handler.u = ieee754sp_abs;
1875 goto scopuop; 1895 goto scopuop;
1876 1896
1877 case fneg_op: 1897 case fneg_op:
1898 MIPS_FPU_EMU_INC_STATS(neg_s);
1878 handler.u = ieee754sp_neg; 1899 handler.u = ieee754sp_neg;
1879 goto scopuop; 1900 goto scopuop;
1880 1901
1881 case fmov_op: 1902 case fmov_op:
1882 /* an easy one */ 1903 /* an easy one */
1904 MIPS_FPU_EMU_INC_STATS(mov_s);
1883 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1905 SPFROMREG(rv.s, MIPSInst_FS(ir));
1884 goto copcsr; 1906 goto copcsr;
1885 1907
@@ -1922,12 +1944,14 @@ copcsr:
1922 return SIGILL; /* not defined */ 1944 return SIGILL; /* not defined */
1923 1945
1924 case fcvtd_op: 1946 case fcvtd_op:
1947 MIPS_FPU_EMU_INC_STATS(cvt_d_s);
1925 SPFROMREG(fs, MIPSInst_FS(ir)); 1948 SPFROMREG(fs, MIPSInst_FS(ir));
1926 rv.d = ieee754dp_fsp(fs); 1949 rv.d = ieee754dp_fsp(fs);
1927 rfmt = d_fmt; 1950 rfmt = d_fmt;
1928 goto copcsr; 1951 goto copcsr;
1929 1952
1930 case fcvtw_op: 1953 case fcvtw_op:
1954 MIPS_FPU_EMU_INC_STATS(cvt_w_s);
1931 SPFROMREG(fs, MIPSInst_FS(ir)); 1955 SPFROMREG(fs, MIPSInst_FS(ir));
1932 rv.w = ieee754sp_tint(fs); 1956 rv.w = ieee754sp_tint(fs);
1933 rfmt = w_fmt; 1957 rfmt = w_fmt;
@@ -1940,6 +1964,15 @@ copcsr:
1940 if (!cpu_has_mips_2_3_4_5_r) 1964 if (!cpu_has_mips_2_3_4_5_r)
1941 return SIGILL; 1965 return SIGILL;
1942 1966
1967 if (MIPSInst_FUNC(ir) == fceil_op)
1968 MIPS_FPU_EMU_INC_STATS(ceil_w_s);
1969 if (MIPSInst_FUNC(ir) == ffloor_op)
1970 MIPS_FPU_EMU_INC_STATS(floor_w_s);
1971 if (MIPSInst_FUNC(ir) == fround_op)
1972 MIPS_FPU_EMU_INC_STATS(round_w_s);
1973 if (MIPSInst_FUNC(ir) == ftrunc_op)
1974 MIPS_FPU_EMU_INC_STATS(trunc_w_s);
1975
1943 oldrm = ieee754_csr.rm; 1976 oldrm = ieee754_csr.rm;
1944 SPFROMREG(fs, MIPSInst_FS(ir)); 1977 SPFROMREG(fs, MIPSInst_FS(ir));
1945 ieee754_csr.rm = MIPSInst_FUNC(ir); 1978 ieee754_csr.rm = MIPSInst_FUNC(ir);
@@ -1952,6 +1985,7 @@ copcsr:
1952 if (!cpu_has_mips_r6) 1985 if (!cpu_has_mips_r6)
1953 return SIGILL; 1986 return SIGILL;
1954 1987
1988 MIPS_FPU_EMU_INC_STATS(sel_s);
1955 SPFROMREG(fd, MIPSInst_FD(ir)); 1989 SPFROMREG(fd, MIPSInst_FD(ir));
1956 if (fd.bits & 0x1) 1990 if (fd.bits & 0x1)
1957 SPFROMREG(rv.s, MIPSInst_FT(ir)); 1991 SPFROMREG(rv.s, MIPSInst_FT(ir));
@@ -1963,6 +1997,7 @@ copcsr:
1963 if (!cpu_has_mips_3_4_5_64_r2_r6) 1997 if (!cpu_has_mips_3_4_5_64_r2_r6)
1964 return SIGILL; 1998 return SIGILL;
1965 1999
2000 MIPS_FPU_EMU_INC_STATS(cvt_l_s);
1966 SPFROMREG(fs, MIPSInst_FS(ir)); 2001 SPFROMREG(fs, MIPSInst_FS(ir));
1967 rv.l = ieee754sp_tlong(fs); 2002 rv.l = ieee754sp_tlong(fs);
1968 rfmt = l_fmt; 2003 rfmt = l_fmt;
@@ -1975,6 +2010,15 @@ copcsr:
1975 if (!cpu_has_mips_3_4_5_64_r2_r6) 2010 if (!cpu_has_mips_3_4_5_64_r2_r6)
1976 return SIGILL; 2011 return SIGILL;
1977 2012
2013 if (MIPSInst_FUNC(ir) == fceill_op)
2014 MIPS_FPU_EMU_INC_STATS(ceil_l_s);
2015 if (MIPSInst_FUNC(ir) == ffloorl_op)
2016 MIPS_FPU_EMU_INC_STATS(floor_l_s);
2017 if (MIPSInst_FUNC(ir) == froundl_op)
2018 MIPS_FPU_EMU_INC_STATS(round_l_s);
2019 if (MIPSInst_FUNC(ir) == ftruncl_op)
2020 MIPS_FPU_EMU_INC_STATS(trunc_l_s);
2021
1978 oldrm = ieee754_csr.rm; 2022 oldrm = ieee754_csr.rm;
1979 SPFROMREG(fs, MIPSInst_FS(ir)); 2023 SPFROMREG(fs, MIPSInst_FS(ir));
1980 ieee754_csr.rm = MIPSInst_FUNC(ir); 2024 ieee754_csr.rm = MIPSInst_FUNC(ir);
@@ -2016,15 +2060,19 @@ copcsr:
2016 switch (MIPSInst_FUNC(ir)) { 2060 switch (MIPSInst_FUNC(ir)) {
2017 /* binary ops */ 2061 /* binary ops */
2018 case fadd_op: 2062 case fadd_op:
2063 MIPS_FPU_EMU_INC_STATS(add_d);
2019 handler.b = ieee754dp_add; 2064 handler.b = ieee754dp_add;
2020 goto dcopbop; 2065 goto dcopbop;
2021 case fsub_op: 2066 case fsub_op:
2067 MIPS_FPU_EMU_INC_STATS(sub_d);
2022 handler.b = ieee754dp_sub; 2068 handler.b = ieee754dp_sub;
2023 goto dcopbop; 2069 goto dcopbop;
2024 case fmul_op: 2070 case fmul_op:
2071 MIPS_FPU_EMU_INC_STATS(mul_d);
2025 handler.b = ieee754dp_mul; 2072 handler.b = ieee754dp_mul;
2026 goto dcopbop; 2073 goto dcopbop;
2027 case fdiv_op: 2074 case fdiv_op:
2075 MIPS_FPU_EMU_INC_STATS(div_d);
2028 handler.b = ieee754dp_div; 2076 handler.b = ieee754dp_div;
2029 goto dcopbop; 2077 goto dcopbop;
2030 2078
@@ -2033,6 +2081,7 @@ copcsr:
2033 if (!cpu_has_mips_2_3_4_5_r) 2081 if (!cpu_has_mips_2_3_4_5_r)
2034 return SIGILL; 2082 return SIGILL;
2035 2083
2084 MIPS_FPU_EMU_INC_STATS(sqrt_d);
2036 handler.u = ieee754dp_sqrt; 2085 handler.u = ieee754dp_sqrt;
2037 goto dcopuop; 2086 goto dcopuop;
2038 /* 2087 /*
@@ -2044,12 +2093,14 @@ copcsr:
2044 if (!cpu_has_mips_4_5_64_r2_r6) 2093 if (!cpu_has_mips_4_5_64_r2_r6)
2045 return SIGILL; 2094 return SIGILL;
2046 2095
2096 MIPS_FPU_EMU_INC_STATS(rsqrt_d);
2047 handler.u = fpemu_dp_rsqrt; 2097 handler.u = fpemu_dp_rsqrt;
2048 goto dcopuop; 2098 goto dcopuop;
2049 case frecip_op: 2099 case frecip_op:
2050 if (!cpu_has_mips_4_5_64_r2_r6) 2100 if (!cpu_has_mips_4_5_64_r2_r6)
2051 return SIGILL; 2101 return SIGILL;
2052 2102
2103 MIPS_FPU_EMU_INC_STATS(recip_d);
2053 handler.u = fpemu_dp_recip; 2104 handler.u = fpemu_dp_recip;
2054 goto dcopuop; 2105 goto dcopuop;
2055 case fmovc_op: 2106 case fmovc_op:
@@ -2083,6 +2134,7 @@ copcsr:
2083 if (!cpu_has_mips_r6) 2134 if (!cpu_has_mips_r6)
2084 return SIGILL; 2135 return SIGILL;
2085 2136
2137 MIPS_FPU_EMU_INC_STATS(seleqz_d);
2086 DPFROMREG(rv.d, MIPSInst_FT(ir)); 2138 DPFROMREG(rv.d, MIPSInst_FT(ir));
2087 if (rv.l & 0x1) 2139 if (rv.l & 0x1)
2088 rv.l = 0; 2140 rv.l = 0;
@@ -2094,6 +2146,7 @@ copcsr:
2094 if (!cpu_has_mips_r6) 2146 if (!cpu_has_mips_r6)
2095 return SIGILL; 2147 return SIGILL;
2096 2148
2149 MIPS_FPU_EMU_INC_STATS(selnez_d);
2097 DPFROMREG(rv.d, MIPSInst_FT(ir)); 2150 DPFROMREG(rv.d, MIPSInst_FT(ir));
2098 if (rv.l & 0x1) 2151 if (rv.l & 0x1)
2099 DPFROMREG(rv.d, MIPSInst_FS(ir)); 2152 DPFROMREG(rv.d, MIPSInst_FS(ir));
@@ -2107,6 +2160,7 @@ copcsr:
2107 if (!cpu_has_mips_r6) 2160 if (!cpu_has_mips_r6)
2108 return SIGILL; 2161 return SIGILL;
2109 2162
2163 MIPS_FPU_EMU_INC_STATS(maddf_d);
2110 DPFROMREG(ft, MIPSInst_FT(ir)); 2164 DPFROMREG(ft, MIPSInst_FT(ir));
2111 DPFROMREG(fs, MIPSInst_FS(ir)); 2165 DPFROMREG(fs, MIPSInst_FS(ir));
2112 DPFROMREG(fd, MIPSInst_FD(ir)); 2166 DPFROMREG(fd, MIPSInst_FD(ir));
@@ -2120,6 +2174,7 @@ copcsr:
2120 if (!cpu_has_mips_r6) 2174 if (!cpu_has_mips_r6)
2121 return SIGILL; 2175 return SIGILL;
2122 2176
2177 MIPS_FPU_EMU_INC_STATS(msubf_d);
2123 DPFROMREG(ft, MIPSInst_FT(ir)); 2178 DPFROMREG(ft, MIPSInst_FT(ir));
2124 DPFROMREG(fs, MIPSInst_FS(ir)); 2179 DPFROMREG(fs, MIPSInst_FS(ir));
2125 DPFROMREG(fd, MIPSInst_FD(ir)); 2180 DPFROMREG(fd, MIPSInst_FD(ir));
@@ -2133,9 +2188,9 @@ copcsr:
2133 if (!cpu_has_mips_r6) 2188 if (!cpu_has_mips_r6)
2134 return SIGILL; 2189 return SIGILL;
2135 2190
2191 MIPS_FPU_EMU_INC_STATS(rint_d);
2136 DPFROMREG(fs, MIPSInst_FS(ir)); 2192 DPFROMREG(fs, MIPSInst_FS(ir));
2137 rv.l = ieee754dp_tlong(fs); 2193 rv.d = ieee754dp_rint(fs);
2138 rv.d = ieee754dp_flong(rv.l);
2139 goto copcsr; 2194 goto copcsr;
2140 } 2195 }
2141 2196
@@ -2145,9 +2200,10 @@ copcsr:
2145 if (!cpu_has_mips_r6) 2200 if (!cpu_has_mips_r6)
2146 return SIGILL; 2201 return SIGILL;
2147 2202
2203 MIPS_FPU_EMU_INC_STATS(class_d);
2148 DPFROMREG(fs, MIPSInst_FS(ir)); 2204 DPFROMREG(fs, MIPSInst_FS(ir));
2149 rv.w = ieee754dp_2008class(fs); 2205 rv.l = ieee754dp_2008class(fs);
2150 rfmt = w_fmt; 2206 rfmt = l_fmt;
2151 break; 2207 break;
2152 } 2208 }
2153 2209
@@ -2157,6 +2213,7 @@ copcsr:
2157 if (!cpu_has_mips_r6) 2213 if (!cpu_has_mips_r6)
2158 return SIGILL; 2214 return SIGILL;
2159 2215
2216 MIPS_FPU_EMU_INC_STATS(min_d);
2160 DPFROMREG(ft, MIPSInst_FT(ir)); 2217 DPFROMREG(ft, MIPSInst_FT(ir));
2161 DPFROMREG(fs, MIPSInst_FS(ir)); 2218 DPFROMREG(fs, MIPSInst_FS(ir));
2162 rv.d = ieee754dp_fmin(fs, ft); 2219 rv.d = ieee754dp_fmin(fs, ft);
@@ -2169,6 +2226,7 @@ copcsr:
2169 if (!cpu_has_mips_r6) 2226 if (!cpu_has_mips_r6)
2170 return SIGILL; 2227 return SIGILL;
2171 2228
2229 MIPS_FPU_EMU_INC_STATS(mina_d);
2172 DPFROMREG(ft, MIPSInst_FT(ir)); 2230 DPFROMREG(ft, MIPSInst_FT(ir));
2173 DPFROMREG(fs, MIPSInst_FS(ir)); 2231 DPFROMREG(fs, MIPSInst_FS(ir));
2174 rv.d = ieee754dp_fmina(fs, ft); 2232 rv.d = ieee754dp_fmina(fs, ft);
@@ -2181,6 +2239,7 @@ copcsr:
2181 if (!cpu_has_mips_r6) 2239 if (!cpu_has_mips_r6)
2182 return SIGILL; 2240 return SIGILL;
2183 2241
2242 MIPS_FPU_EMU_INC_STATS(max_d);
2184 DPFROMREG(ft, MIPSInst_FT(ir)); 2243 DPFROMREG(ft, MIPSInst_FT(ir));
2185 DPFROMREG(fs, MIPSInst_FS(ir)); 2244 DPFROMREG(fs, MIPSInst_FS(ir));
2186 rv.d = ieee754dp_fmax(fs, ft); 2245 rv.d = ieee754dp_fmax(fs, ft);
@@ -2193,6 +2252,7 @@ copcsr:
2193 if (!cpu_has_mips_r6) 2252 if (!cpu_has_mips_r6)
2194 return SIGILL; 2253 return SIGILL;
2195 2254
2255 MIPS_FPU_EMU_INC_STATS(maxa_d);
2196 DPFROMREG(ft, MIPSInst_FT(ir)); 2256 DPFROMREG(ft, MIPSInst_FT(ir));
2197 DPFROMREG(fs, MIPSInst_FS(ir)); 2257 DPFROMREG(fs, MIPSInst_FS(ir));
2198 rv.d = ieee754dp_fmaxa(fs, ft); 2258 rv.d = ieee754dp_fmaxa(fs, ft);
@@ -2200,15 +2260,18 @@ copcsr:
2200 } 2260 }
2201 2261
2202 case fabs_op: 2262 case fabs_op:
2263 MIPS_FPU_EMU_INC_STATS(abs_d);
2203 handler.u = ieee754dp_abs; 2264 handler.u = ieee754dp_abs;
2204 goto dcopuop; 2265 goto dcopuop;
2205 2266
2206 case fneg_op: 2267 case fneg_op:
2268 MIPS_FPU_EMU_INC_STATS(neg_d);
2207 handler.u = ieee754dp_neg; 2269 handler.u = ieee754dp_neg;
2208 goto dcopuop; 2270 goto dcopuop;
2209 2271
2210 case fmov_op: 2272 case fmov_op:
2211 /* an easy one */ 2273 /* an easy one */
2274 MIPS_FPU_EMU_INC_STATS(mov_d);
2212 DPFROMREG(rv.d, MIPSInst_FS(ir)); 2275 DPFROMREG(rv.d, MIPSInst_FS(ir));
2213 goto copcsr; 2276 goto copcsr;
2214 2277
@@ -2228,6 +2291,7 @@ dcopuop:
2228 * unary conv ops 2291 * unary conv ops
2229 */ 2292 */
2230 case fcvts_op: 2293 case fcvts_op:
2294 MIPS_FPU_EMU_INC_STATS(cvt_s_d);
2231 DPFROMREG(fs, MIPSInst_FS(ir)); 2295 DPFROMREG(fs, MIPSInst_FS(ir));
2232 rv.s = ieee754sp_fdp(fs); 2296 rv.s = ieee754sp_fdp(fs);
2233 rfmt = s_fmt; 2297 rfmt = s_fmt;
@@ -2237,6 +2301,7 @@ dcopuop:
2237 return SIGILL; /* not defined */ 2301 return SIGILL; /* not defined */
2238 2302
2239 case fcvtw_op: 2303 case fcvtw_op:
2304 MIPS_FPU_EMU_INC_STATS(cvt_w_d);
2240 DPFROMREG(fs, MIPSInst_FS(ir)); 2305 DPFROMREG(fs, MIPSInst_FS(ir));
2241 rv.w = ieee754dp_tint(fs); /* wrong */ 2306 rv.w = ieee754dp_tint(fs); /* wrong */
2242 rfmt = w_fmt; 2307 rfmt = w_fmt;
@@ -2249,6 +2314,15 @@ dcopuop:
2249 if (!cpu_has_mips_2_3_4_5_r) 2314 if (!cpu_has_mips_2_3_4_5_r)
2250 return SIGILL; 2315 return SIGILL;
2251 2316
2317 if (MIPSInst_FUNC(ir) == fceil_op)
2318 MIPS_FPU_EMU_INC_STATS(ceil_w_d);
2319 if (MIPSInst_FUNC(ir) == ffloor_op)
2320 MIPS_FPU_EMU_INC_STATS(floor_w_d);
2321 if (MIPSInst_FUNC(ir) == fround_op)
2322 MIPS_FPU_EMU_INC_STATS(round_w_d);
2323 if (MIPSInst_FUNC(ir) == ftrunc_op)
2324 MIPS_FPU_EMU_INC_STATS(trunc_w_d);
2325
2252 oldrm = ieee754_csr.rm; 2326 oldrm = ieee754_csr.rm;
2253 DPFROMREG(fs, MIPSInst_FS(ir)); 2327 DPFROMREG(fs, MIPSInst_FS(ir));
2254 ieee754_csr.rm = MIPSInst_FUNC(ir); 2328 ieee754_csr.rm = MIPSInst_FUNC(ir);
@@ -2261,6 +2335,7 @@ dcopuop:
2261 if (!cpu_has_mips_r6) 2335 if (!cpu_has_mips_r6)
2262 return SIGILL; 2336 return SIGILL;
2263 2337
2338 MIPS_FPU_EMU_INC_STATS(sel_d);
2264 DPFROMREG(fd, MIPSInst_FD(ir)); 2339 DPFROMREG(fd, MIPSInst_FD(ir));
2265 if (fd.bits & 0x1) 2340 if (fd.bits & 0x1)
2266 DPFROMREG(rv.d, MIPSInst_FT(ir)); 2341 DPFROMREG(rv.d, MIPSInst_FT(ir));
@@ -2272,6 +2347,7 @@ dcopuop:
2272 if (!cpu_has_mips_3_4_5_64_r2_r6) 2347 if (!cpu_has_mips_3_4_5_64_r2_r6)
2273 return SIGILL; 2348 return SIGILL;
2274 2349
2350 MIPS_FPU_EMU_INC_STATS(cvt_l_d);
2275 DPFROMREG(fs, MIPSInst_FS(ir)); 2351 DPFROMREG(fs, MIPSInst_FS(ir));
2276 rv.l = ieee754dp_tlong(fs); 2352 rv.l = ieee754dp_tlong(fs);
2277 rfmt = l_fmt; 2353 rfmt = l_fmt;
@@ -2284,6 +2360,15 @@ dcopuop:
2284 if (!cpu_has_mips_3_4_5_64_r2_r6) 2360 if (!cpu_has_mips_3_4_5_64_r2_r6)
2285 return SIGILL; 2361 return SIGILL;
2286 2362
2363 if (MIPSInst_FUNC(ir) == fceill_op)
2364 MIPS_FPU_EMU_INC_STATS(ceil_l_d);
2365 if (MIPSInst_FUNC(ir) == ffloorl_op)
2366 MIPS_FPU_EMU_INC_STATS(floor_l_d);
2367 if (MIPSInst_FUNC(ir) == froundl_op)
2368 MIPS_FPU_EMU_INC_STATS(round_l_d);
2369 if (MIPSInst_FUNC(ir) == ftruncl_op)
2370 MIPS_FPU_EMU_INC_STATS(trunc_l_d);
2371
2287 oldrm = ieee754_csr.rm; 2372 oldrm = ieee754_csr.rm;
2288 DPFROMREG(fs, MIPSInst_FS(ir)); 2373 DPFROMREG(fs, MIPSInst_FS(ir));
2289 ieee754_csr.rm = MIPSInst_FUNC(ir); 2374 ieee754_csr.rm = MIPSInst_FUNC(ir);
@@ -2325,12 +2410,14 @@ dcopuop:
2325 switch (MIPSInst_FUNC(ir)) { 2410 switch (MIPSInst_FUNC(ir)) {
2326 case fcvts_op: 2411 case fcvts_op:
2327 /* convert word to single precision real */ 2412 /* convert word to single precision real */
2413 MIPS_FPU_EMU_INC_STATS(cvt_s_w);
2328 SPFROMREG(fs, MIPSInst_FS(ir)); 2414 SPFROMREG(fs, MIPSInst_FS(ir));
2329 rv.s = ieee754sp_fint(fs.bits); 2415 rv.s = ieee754sp_fint(fs.bits);
2330 rfmt = s_fmt; 2416 rfmt = s_fmt;
2331 goto copcsr; 2417 goto copcsr;
2332 case fcvtd_op: 2418 case fcvtd_op:
2333 /* convert word to double precision real */ 2419 /* convert word to double precision real */
2420 MIPS_FPU_EMU_INC_STATS(cvt_d_w);
2334 SPFROMREG(fs, MIPSInst_FS(ir)); 2421 SPFROMREG(fs, MIPSInst_FS(ir));
2335 rv.d = ieee754dp_fint(fs.bits); 2422 rv.d = ieee754dp_fint(fs.bits);
2336 rfmt = d_fmt; 2423 rfmt = d_fmt;
@@ -2350,6 +2437,90 @@ dcopuop:
2350 (MIPSInst_FUNC(ir) & 0x20)) 2437 (MIPSInst_FUNC(ir) & 0x20))
2351 return SIGILL; 2438 return SIGILL;
2352 2439
2440 if (!sig) {
2441 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2442 switch (cmpop) {
2443 case 0:
2444 MIPS_FPU_EMU_INC_STATS(cmp_af_s);
2445 break;
2446 case 1:
2447 MIPS_FPU_EMU_INC_STATS(cmp_un_s);
2448 break;
2449 case 2:
2450 MIPS_FPU_EMU_INC_STATS(cmp_eq_s);
2451 break;
2452 case 3:
2453 MIPS_FPU_EMU_INC_STATS(cmp_ueq_s);
2454 break;
2455 case 4:
2456 MIPS_FPU_EMU_INC_STATS(cmp_lt_s);
2457 break;
2458 case 5:
2459 MIPS_FPU_EMU_INC_STATS(cmp_ult_s);
2460 break;
2461 case 6:
2462 MIPS_FPU_EMU_INC_STATS(cmp_le_s);
2463 break;
2464 case 7:
2465 MIPS_FPU_EMU_INC_STATS(cmp_ule_s);
2466 break;
2467 }
2468 } else {
2469 switch (cmpop) {
2470 case 1:
2471 MIPS_FPU_EMU_INC_STATS(cmp_or_s);
2472 break;
2473 case 2:
2474 MIPS_FPU_EMU_INC_STATS(cmp_une_s);
2475 break;
2476 case 3:
2477 MIPS_FPU_EMU_INC_STATS(cmp_ne_s);
2478 break;
2479 }
2480 }
2481 } else {
2482 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2483 switch (cmpop) {
2484 case 0:
2485 MIPS_FPU_EMU_INC_STATS(cmp_saf_s);
2486 break;
2487 case 1:
2488 MIPS_FPU_EMU_INC_STATS(cmp_sun_s);
2489 break;
2490 case 2:
2491 MIPS_FPU_EMU_INC_STATS(cmp_seq_s);
2492 break;
2493 case 3:
2494 MIPS_FPU_EMU_INC_STATS(cmp_sueq_s);
2495 break;
2496 case 4:
2497 MIPS_FPU_EMU_INC_STATS(cmp_slt_s);
2498 break;
2499 case 5:
2500 MIPS_FPU_EMU_INC_STATS(cmp_sult_s);
2501 break;
2502 case 6:
2503 MIPS_FPU_EMU_INC_STATS(cmp_sle_s);
2504 break;
2505 case 7:
2506 MIPS_FPU_EMU_INC_STATS(cmp_sule_s);
2507 break;
2508 }
2509 } else {
2510 switch (cmpop) {
2511 case 1:
2512 MIPS_FPU_EMU_INC_STATS(cmp_sor_s);
2513 break;
2514 case 2:
2515 MIPS_FPU_EMU_INC_STATS(cmp_sune_s);
2516 break;
2517 case 3:
2518 MIPS_FPU_EMU_INC_STATS(cmp_sne_s);
2519 break;
2520 }
2521 }
2522 }
2523
2353 /* fmt is w_fmt for single precision so fix it */ 2524 /* fmt is w_fmt for single precision so fix it */
2354 rfmt = s_fmt; 2525 rfmt = s_fmt;
2355 /* default to false */ 2526 /* default to false */
@@ -2394,6 +2565,7 @@ dcopuop:
2394 break; 2565 break;
2395 } 2566 }
2396 } 2567 }
2568 break;
2397 } 2569 }
2398 2570
2399 case l_fmt: 2571 case l_fmt:
@@ -2406,11 +2578,13 @@ dcopuop:
2406 switch (MIPSInst_FUNC(ir)) { 2578 switch (MIPSInst_FUNC(ir)) {
2407 case fcvts_op: 2579 case fcvts_op:
2408 /* convert long to single precision real */ 2580 /* convert long to single precision real */
2581 MIPS_FPU_EMU_INC_STATS(cvt_s_l);
2409 rv.s = ieee754sp_flong(bits); 2582 rv.s = ieee754sp_flong(bits);
2410 rfmt = s_fmt; 2583 rfmt = s_fmt;
2411 goto copcsr; 2584 goto copcsr;
2412 case fcvtd_op: 2585 case fcvtd_op:
2413 /* convert long to double precision real */ 2586 /* convert long to double precision real */
2587 MIPS_FPU_EMU_INC_STATS(cvt_d_l);
2414 rv.d = ieee754dp_flong(bits); 2588 rv.d = ieee754dp_flong(bits);
2415 rfmt = d_fmt; 2589 rfmt = d_fmt;
2416 goto copcsr; 2590 goto copcsr;
@@ -2424,6 +2598,90 @@ dcopuop:
2424 (MIPSInst_FUNC(ir) & 0x20)) 2598 (MIPSInst_FUNC(ir) & 0x20))
2425 return SIGILL; 2599 return SIGILL;
2426 2600
2601 if (!sig) {
2602 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2603 switch (cmpop) {
2604 case 0:
2605 MIPS_FPU_EMU_INC_STATS(cmp_af_d);
2606 break;
2607 case 1:
2608 MIPS_FPU_EMU_INC_STATS(cmp_un_d);
2609 break;
2610 case 2:
2611 MIPS_FPU_EMU_INC_STATS(cmp_eq_d);
2612 break;
2613 case 3:
2614 MIPS_FPU_EMU_INC_STATS(cmp_ueq_d);
2615 break;
2616 case 4:
2617 MIPS_FPU_EMU_INC_STATS(cmp_lt_d);
2618 break;
2619 case 5:
2620 MIPS_FPU_EMU_INC_STATS(cmp_ult_d);
2621 break;
2622 case 6:
2623 MIPS_FPU_EMU_INC_STATS(cmp_le_d);
2624 break;
2625 case 7:
2626 MIPS_FPU_EMU_INC_STATS(cmp_ule_d);
2627 break;
2628 }
2629 } else {
2630 switch (cmpop) {
2631 case 1:
2632 MIPS_FPU_EMU_INC_STATS(cmp_or_d);
2633 break;
2634 case 2:
2635 MIPS_FPU_EMU_INC_STATS(cmp_une_d);
2636 break;
2637 case 3:
2638 MIPS_FPU_EMU_INC_STATS(cmp_ne_d);
2639 break;
2640 }
2641 }
2642 } else {
2643 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2644 switch (cmpop) {
2645 case 0:
2646 MIPS_FPU_EMU_INC_STATS(cmp_saf_d);
2647 break;
2648 case 1:
2649 MIPS_FPU_EMU_INC_STATS(cmp_sun_d);
2650 break;
2651 case 2:
2652 MIPS_FPU_EMU_INC_STATS(cmp_seq_d);
2653 break;
2654 case 3:
2655 MIPS_FPU_EMU_INC_STATS(cmp_sueq_d);
2656 break;
2657 case 4:
2658 MIPS_FPU_EMU_INC_STATS(cmp_slt_d);
2659 break;
2660 case 5:
2661 MIPS_FPU_EMU_INC_STATS(cmp_sult_d);
2662 break;
2663 case 6:
2664 MIPS_FPU_EMU_INC_STATS(cmp_sle_d);
2665 break;
2666 case 7:
2667 MIPS_FPU_EMU_INC_STATS(cmp_sule_d);
2668 break;
2669 }
2670 } else {
2671 switch (cmpop) {
2672 case 1:
2673 MIPS_FPU_EMU_INC_STATS(cmp_sor_d);
2674 break;
2675 case 2:
2676 MIPS_FPU_EMU_INC_STATS(cmp_sune_d);
2677 break;
2678 case 3:
2679 MIPS_FPU_EMU_INC_STATS(cmp_sne_d);
2680 break;
2681 }
2682 }
2683 }
2684
2427 /* fmt is l_fmt for double precision so fix it */ 2685 /* fmt is l_fmt for double precision so fix it */
2428 rfmt = d_fmt; 2686 rfmt = d_fmt;
2429 /* default to false */ 2687 /* default to false */
@@ -2468,6 +2726,8 @@ dcopuop:
2468 break; 2726 break;
2469 } 2727 }
2470 } 2728 }
2729 break;
2730
2471 default: 2731 default:
2472 return SIGILL; 2732 return SIGILL;
2473 } 2733 }
@@ -2553,7 +2813,7 @@ dcopuop:
2553 * For simplicity we always terminate upon an ISA mode switch. 2813 * For simplicity we always terminate upon an ISA mode switch.
2554 */ 2814 */
2555int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 2815int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2556 int has_fpu, void *__user *fault_addr) 2816 int has_fpu, void __user **fault_addr)
2557{ 2817{
2558 unsigned long oldepc, prevepc; 2818 unsigned long oldepc, prevepc;
2559 struct mm_decoded_insn dec_insn; 2819 struct mm_decoded_insn dec_insn;
diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c
index fd71b8daaaf2..5bec64f2884e 100644
--- a/arch/mips/math-emu/dp_fmax.c
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48 return ieee754dp_nanxcpt(x); 48 return ieee754dp_nanxcpt(x);
49 49
50 /* numbers are preferred to NaNs */ 50 /*
51 * Quiet NaN handling
52 */
53
54 /*
55 * The case of both inputs quiet NaNs
56 */
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 return x;
59
60 /*
61 * The cases of exactly one input quiet NaN (numbers
62 * are here preferred as returned values to NaNs)
63 */
51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 64 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 65 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 66 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 67 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55 return x; 68 return x;
56 69
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 70 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 71 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 72 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
80 return ys ? x : y; 92 return ys ? x : y;
81 93
82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 94 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83 if (xs == ys) 95 return ieee754dp_zero(xs & ys);
84 return x;
85 return ieee754dp_zero(1);
86 96
87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 97 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88 DPDNORMX; 98 DPDNORMX;
@@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
106 else if (xs < ys) 116 else if (xs < ys)
107 return x; 117 return x;
108 118
109 /* Compare exponent */ 119 /* Signs of inputs are equal, let's compare exponents */
110 if (xe > ye) 120 if (xs == 0) {
111 return x; 121 /* Inputs are both positive */
112 else if (xe < ye) 122 if (xe > ye)
113 return y; 123 return x;
124 else if (xe < ye)
125 return y;
126 } else {
127 /* Inputs are both negative */
128 if (xe > ye)
129 return y;
130 else if (xe < ye)
131 return x;
132 }
114 133
115 /* Compare mantissa */ 134 /* Signs and exponents of inputs are equal, let's compare mantissas */
135 if (xs == 0) {
136 /* Inputs are both positive, with equal signs and exponents */
137 if (xm <= ym)
138 return y;
139 return x;
140 }
141 /* Inputs are both negative, with equal signs and exponents */
116 if (xm <= ym) 142 if (xm <= ym)
117 return y; 143 return x;
118 return x; 144 return y;
119} 145}
120 146
121union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) 147union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
@@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
147 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 173 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148 return ieee754dp_nanxcpt(x); 174 return ieee754dp_nanxcpt(x);
149 175
150 /* numbers are preferred to NaNs */ 176 /*
177 * Quiet NaN handling
178 */
179
180 /*
181 * The case of both inputs quiet NaNs
182 */
183 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
184 return x;
185
186 /*
187 * The cases of exactly one input quiet NaN (numbers
188 * are here preferred as returned values to NaNs)
189 */
151 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 190 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 191 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 192 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 193 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155 return x; 194 return x;
156 195
157 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 196 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 197 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 198 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -164,6 +202,9 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
164 /* 202 /*
165 * Infinity and zero handling 203 * Infinity and zero handling
166 */ 204 */
205 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
206 return ieee754dp_inf(xs & ys);
207
167 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 208 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 209 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 210 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -171,7 +212,6 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
171 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 212 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172 return x; 213 return x;
173 214
174 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 215 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 216 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 217 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
@@ -180,9 +220,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
180 return y; 220 return y;
181 221
182 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 222 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183 if (xs == ys) 223 return ieee754dp_zero(xs & ys);
184 return x;
185 return ieee754dp_zero(1);
186 224
187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 225 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188 DPDNORMX; 226 DPDNORMX;
@@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
207 return y; 245 return y;
208 246
209 /* Compare mantissa */ 247 /* Compare mantissa */
210 if (xm <= ym) 248 if (xm < ym)
211 return y; 249 return y;
212 return x; 250 else if (xm > ym)
251 return x;
252 else if (xs == 0)
253 return x;
254 return y;
213} 255}
diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c
index c1072b0dfb95..a287b23818d8 100644
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48 return ieee754dp_nanxcpt(x); 48 return ieee754dp_nanxcpt(x);
49 49
50 /* numbers are preferred to NaNs */ 50 /*
51 * Quiet NaN handling
52 */
53
54 /*
55 * The case of both inputs quiet NaNs
56 */
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 return x;
59
60 /*
61 * The cases of exactly one input quiet NaN (numbers
62 * are here preferred as returned values to NaNs)
63 */
51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 64 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 65 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 66 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 67 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55 return x; 68 return x;
56 69
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 70 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 71 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 72 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
80 return ys ? y : x; 92 return ys ? y : x;
81 93
82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 94 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83 if (xs == ys) 95 return ieee754dp_zero(xs | ys);
84 return x;
85 return ieee754dp_zero(1);
86 96
87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 97 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88 DPDNORMX; 98 DPDNORMX;
@@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
106 else if (xs < ys) 116 else if (xs < ys)
107 return y; 117 return y;
108 118
109 /* Compare exponent */ 119 /* Signs of inputs are the same, let's compare exponents */
110 if (xe > ye) 120 if (xs == 0) {
111 return y; 121 /* Inputs are both positive */
112 else if (xe < ye) 122 if (xe > ye)
113 return x; 123 return y;
124 else if (xe < ye)
125 return x;
126 } else {
127 /* Inputs are both negative */
128 if (xe > ye)
129 return x;
130 else if (xe < ye)
131 return y;
132 }
114 133
115 /* Compare mantissa */ 134 /* Signs and exponents of inputs are equal, let's compare mantissas */
135 if (xs == 0) {
136 /* Inputs are both positive, with equal signs and exponents */
137 if (xm <= ym)
138 return x;
139 return y;
140 }
141 /* Inputs are both negative, with equal signs and exponents */
116 if (xm <= ym) 142 if (xm <= ym)
117 return x; 143 return y;
118 return y; 144 return x;
119} 145}
120 146
121union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) 147union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
@@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
147 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 173 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148 return ieee754dp_nanxcpt(x); 174 return ieee754dp_nanxcpt(x);
149 175
150 /* numbers are preferred to NaNs */ 176 /*
177 * Quiet NaN handling
178 */
179
180 /*
181 * The case of both inputs quiet NaNs
182 */
183 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
184 return x;
185
186 /*
187 * The cases of exactly one input quiet NaN (numbers
188 * are here preferred as returned values to NaNs)
189 */
151 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 190 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 191 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 192 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 193 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155 return x; 194 return x;
156 195
157 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 196 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 197 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 198 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -164,25 +202,25 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
164 /* 202 /*
165 * Infinity and zero handling 203 * Infinity and zero handling
166 */ 204 */
205 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
206 return ieee754dp_inf(xs | ys);
207
167 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 208 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 209 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 210 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 211 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 212 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172 return x; 213 return y;
173 214
174 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 215 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 216 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 217 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 218 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 219 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180 return y; 220 return x;
181 221
182 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 222 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183 if (xs == ys) 223 return ieee754dp_zero(xs | ys);
184 return x;
185 return ieee754dp_zero(1);
186 224
187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 225 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188 DPDNORMX; 226 DPDNORMX;
@@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
207 return x; 245 return x;
208 246
209 /* Compare mantissa */ 247 /* Compare mantissa */
210 if (xm <= ym) 248 if (xm < ym)
249 return x;
250 else if (xm > ym)
251 return y;
252 else if (xs == 1)
211 return x; 253 return x;
212 return y; 254 return y;
213} 255}
diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c
index caa62f20a888..e0d9be5fbf4c 100644
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -14,22 +14,45 @@
14 14
15#include "ieee754dp.h" 15#include "ieee754dp.h"
16 16
17enum maddf_flags { 17
18 maddf_negate_product = 1 << 0, 18/* 128 bits shift right logical with rounding. */
19}; 19void srl128(u64 *hptr, u64 *lptr, int count)
20{
21 u64 low;
22
23 if (count >= 128) {
24 *lptr = *hptr != 0 || *lptr != 0;
25 *hptr = 0;
26 } else if (count >= 64) {
27 if (count == 64) {
28 *lptr = *hptr | (*lptr != 0);
29 } else {
30 low = *lptr;
31 *lptr = *hptr >> (count - 64);
32 *lptr |= (*hptr << (128 - count)) != 0 || low != 0;
33 }
34 *hptr = 0;
35 } else {
36 low = *lptr;
37 *lptr = low >> count | *hptr << (64 - count);
38 *lptr |= (low << (64 - count)) != 0;
39 *hptr = *hptr >> count;
40 }
41}
20 42
21static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, 43static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
22 union ieee754dp y, enum maddf_flags flags) 44 union ieee754dp y, enum maddf_flags flags)
23{ 45{
24 int re; 46 int re;
25 int rs; 47 int rs;
26 u64 rm;
27 unsigned lxm; 48 unsigned lxm;
28 unsigned hxm; 49 unsigned hxm;
29 unsigned lym; 50 unsigned lym;
30 unsigned hym; 51 unsigned hym;
31 u64 lrm; 52 u64 lrm;
32 u64 hrm; 53 u64 hrm;
54 u64 lzm;
55 u64 hzm;
33 u64 t; 56 u64 t;
34 u64 at; 57 u64 at;
35 int s; 58 int s;
@@ -48,52 +71,34 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
48 71
49 ieee754_clearcx(); 72 ieee754_clearcx();
50 73
51 switch (zc) { 74 /*
52 case IEEE754_CLASS_SNAN: 75 * Handle the cases when at least one of x, y or z is a NaN.
53 ieee754_setcx(IEEE754_INVALID_OPERATION); 76 * Order of precedence is sNaN, qNaN and z, x, y.
77 */
78 if (zc == IEEE754_CLASS_SNAN)
54 return ieee754dp_nanxcpt(z); 79 return ieee754dp_nanxcpt(z);
55 case IEEE754_CLASS_DNORM: 80 if (xc == IEEE754_CLASS_SNAN)
56 DPDNORMZ;
57 /* QNAN and ZERO cases are handled separately below */
58 }
59
60 switch (CLPAIR(xc, yc)) {
61 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
62 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
63 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
64 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
65 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
66 return ieee754dp_nanxcpt(y);
67
68 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
69 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
70 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
71 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
72 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
73 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
74 return ieee754dp_nanxcpt(x); 81 return ieee754dp_nanxcpt(x);
75 82 if (yc == IEEE754_CLASS_SNAN)
76 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 83 return ieee754dp_nanxcpt(y);
77 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 84 if (zc == IEEE754_CLASS_QNAN)
78 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 85 return z;
79 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 86 if (xc == IEEE754_CLASS_QNAN)
87 return x;
88 if (yc == IEEE754_CLASS_QNAN)
80 return y; 89 return y;
81 90
82 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 91 if (zc == IEEE754_CLASS_DNORM)
83 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 92 DPDNORMZ;
84 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 93 /* ZERO z cases are handled separately below */
85 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
86 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
87 return x;
88 94
95 switch (CLPAIR(xc, yc)) {
89 96
90 /* 97 /*
91 * Infinity handling 98 * Infinity handling
92 */ 99 */
93 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 100 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
94 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 101 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
95 if (zc == IEEE754_CLASS_QNAN)
96 return z;
97 ieee754_setcx(IEEE754_INVALID_OPERATION); 102 ieee754_setcx(IEEE754_INVALID_OPERATION);
98 return ieee754dp_indef(); 103 return ieee754dp_indef();
99 104
@@ -102,9 +107,27 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
102 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 107 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
103 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 108 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
104 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 109 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
105 if (zc == IEEE754_CLASS_QNAN) 110 if ((zc == IEEE754_CLASS_INF) &&
106 return z; 111 ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
107 return ieee754dp_inf(xs ^ ys); 112 ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
113 /*
114 * Cases of addition of infinities with opposite signs
115 * or subtraction of infinities with same signs.
116 */
117 ieee754_setcx(IEEE754_INVALID_OPERATION);
118 return ieee754dp_indef();
119 }
120 /*
121 * z is here either not an infinity, or an infinity having the
122 * same sign as product (x*y) (in case of MADDF.D instruction)
123 * or product -(x*y) (in MSUBF.D case). The result must be an
124 * infinity, and its sign is determined only by the value of
125 * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
126 */
127 if (flags & MADDF_NEGATE_PRODUCT)
128 return ieee754dp_inf(1 ^ (xs ^ ys));
129 else
130 return ieee754dp_inf(xs ^ ys);
108 131
109 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 132 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
110 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 133 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
@@ -113,32 +136,42 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
113 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 136 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
114 if (zc == IEEE754_CLASS_INF) 137 if (zc == IEEE754_CLASS_INF)
115 return ieee754dp_inf(zs); 138 return ieee754dp_inf(zs);
116 /* Multiplication is 0 so just return z */ 139 if (zc == IEEE754_CLASS_ZERO) {
140 /* Handle cases +0 + (-0) and similar ones. */
141 if ((!(flags & MADDF_NEGATE_PRODUCT)
142 && (zs == (xs ^ ys))) ||
143 ((flags & MADDF_NEGATE_PRODUCT)
144 && (zs != (xs ^ ys))))
145 /*
146 * Cases of addition of zeros of equal signs
147 * or subtraction of zeroes of opposite signs.
148 * The sign of the resulting zero is in any
149 * such case determined only by the sign of z.
150 */
151 return z;
152
153 return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
154 }
155 /* x*y is here 0, and z is not 0, so just return z */
117 return z; 156 return z;
118 157
119 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 158 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
120 DPDNORMX; 159 DPDNORMX;
121 160
122 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 161 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
123 if (zc == IEEE754_CLASS_QNAN) 162 if (zc == IEEE754_CLASS_INF)
124 return z;
125 else if (zc == IEEE754_CLASS_INF)
126 return ieee754dp_inf(zs); 163 return ieee754dp_inf(zs);
127 DPDNORMY; 164 DPDNORMY;
128 break; 165 break;
129 166
130 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 167 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
131 if (zc == IEEE754_CLASS_QNAN) 168 if (zc == IEEE754_CLASS_INF)
132 return z;
133 else if (zc == IEEE754_CLASS_INF)
134 return ieee754dp_inf(zs); 169 return ieee754dp_inf(zs);
135 DPDNORMX; 170 DPDNORMX;
136 break; 171 break;
137 172
138 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): 173 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
139 if (zc == IEEE754_CLASS_QNAN) 174 if (zc == IEEE754_CLASS_INF)
140 return z;
141 else if (zc == IEEE754_CLASS_INF)
142 return ieee754dp_inf(zs); 175 return ieee754dp_inf(zs);
143 /* fall through to real computations */ 176 /* fall through to real computations */
144 } 177 }
@@ -157,7 +190,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
157 190
158 re = xe + ye; 191 re = xe + ye;
159 rs = xs ^ ys; 192 rs = xs ^ ys;
160 if (flags & maddf_negate_product) 193 if (flags & MADDF_NEGATE_PRODUCT)
161 rs ^= 1; 194 rs ^= 1;
162 195
163 /* shunt to top of word */ 196 /* shunt to top of word */
@@ -165,7 +198,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
165 ym <<= 64 - (DP_FBITS + 1); 198 ym <<= 64 - (DP_FBITS + 1);
166 199
167 /* 200 /*
168 * Multiply 64 bits xm, ym to give high 64 bits rm with stickness. 201 * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm.
169 */ 202 */
170 203
171 /* 32 * 32 => 64 */ 204 /* 32 * 32 => 64 */
@@ -195,81 +228,110 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
195 228
196 hrm = hrm + (t >> 32); 229 hrm = hrm + (t >> 32);
197 230
198 rm = hrm | (lrm != 0); 231 /* Put explicit bit at bit 126 if necessary */
199 232 if ((int64_t)hrm < 0) {
200 /* 233 lrm = (hrm << 63) | (lrm >> 1);
201 * Sticky shift down to normal rounding precision. 234 hrm = hrm >> 1;
202 */
203 if ((s64) rm < 0) {
204 rm = (rm >> (64 - (DP_FBITS + 1 + 3))) |
205 ((rm << (DP_FBITS + 1 + 3)) != 0);
206 re++; 235 re++;
207 } else {
208 rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) |
209 ((rm << (DP_FBITS + 1 + 3 + 1)) != 0);
210 } 236 }
211 assert(rm & (DP_HIDDEN_BIT << 3));
212 237
213 if (zc == IEEE754_CLASS_ZERO) 238 assert(hrm & (1 << 62));
214 return ieee754dp_format(rs, re, rm);
215 239
216 /* And now the addition */ 240 if (zc == IEEE754_CLASS_ZERO) {
217 assert(zm & DP_HIDDEN_BIT); 241 /*
242 * Move explicit bit from bit 126 to bit 55 since the
243 * ieee754dp_format code expects the mantissa to be
244 * 56 bits wide (53 + 3 rounding bits).
245 */
246 srl128(&hrm, &lrm, (126 - 55));
247 return ieee754dp_format(rs, re, lrm);
248 }
218 249
219 /* 250 /* Move explicit bit from bit 52 to bit 126 */
220 * Provide guard,round and stick bit space. 251 lzm = 0;
221 */ 252 hzm = zm << 10;
222 zm <<= 3; 253 assert(hzm & (1 << 62));
223 254
255 /* Make the exponents the same */
224 if (ze > re) { 256 if (ze > re) {
225 /* 257 /*
226 * Have to shift y fraction right to align. 258 * Have to shift y fraction right to align.
227 */ 259 */
228 s = ze - re; 260 s = ze - re;
229 rm = XDPSRS(rm, s); 261 srl128(&hrm, &lrm, s);
230 re += s; 262 re += s;
231 } else if (re > ze) { 263 } else if (re > ze) {
232 /* 264 /*
233 * Have to shift x fraction right to align. 265 * Have to shift x fraction right to align.
234 */ 266 */
235 s = re - ze; 267 s = re - ze;
236 zm = XDPSRS(zm, s); 268 srl128(&hzm, &lzm, s);
237 ze += s; 269 ze += s;
238 } 270 }
239 assert(ze == re); 271 assert(ze == re);
240 assert(ze <= DP_EMAX); 272 assert(ze <= DP_EMAX);
241 273
274 /* Do the addition */
242 if (zs == rs) { 275 if (zs == rs) {
243 /* 276 /*
244 * Generate 28 bit result of adding two 27 bit numbers 277 * Generate 128 bit result by adding two 127 bit numbers
245 * leaving result in xm, xs and xe. 278 * leaving result in hzm:lzm, zs and ze.
246 */ 279 */
247 zm = zm + rm; 280 hzm = hzm + hrm + (lzm > (lzm + lrm));
248 281 lzm = lzm + lrm;
249 if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */ 282 if ((int64_t)hzm < 0) { /* carry out */
250 zm = XDPSRS1(zm); 283 srl128(&hzm, &lzm, 1);
251 ze++; 284 ze++;
252 } 285 }
253 } else { 286 } else {
254 if (zm >= rm) { 287 if (hzm > hrm || (hzm == hrm && lzm >= lrm)) {
255 zm = zm - rm; 288 hzm = hzm - hrm - (lzm < lrm);
289 lzm = lzm - lrm;
256 } else { 290 } else {
257 zm = rm - zm; 291 hzm = hrm - hzm - (lrm < lzm);
292 lzm = lrm - lzm;
258 zs = rs; 293 zs = rs;
259 } 294 }
260 if (zm == 0) 295 if (lzm == 0 && hzm == 0)
261 return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD); 296 return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
262 297
263 /* 298 /*
264 * Normalize to rounding precision. 299 * Put explicit bit at bit 126 if necessary.
265 */ 300 */
266 while ((zm >> (DP_FBITS + 3)) == 0) { 301 if (hzm == 0) {
267 zm <<= 1; 302 /* left shift by 63 or 64 bits */
268 ze--; 303 if ((int64_t)lzm < 0) {
304 /* MSB of lzm is the explicit bit */
305 hzm = lzm >> 1;
306 lzm = lzm << 63;
307 ze -= 63;
308 } else {
309 hzm = lzm;
310 lzm = 0;
311 ze -= 64;
312 }
313 }
314
315 t = 0;
316 while ((hzm >> (62 - t)) == 0)
317 t++;
318
319 assert(t <= 62);
320 if (t) {
321 hzm = hzm << t | lzm >> (64 - t);
322 lzm = lzm << t;
323 ze -= t;
269 } 324 }
270 } 325 }
271 326
272 return ieee754dp_format(zs, ze, zm); 327 /*
328 * Move explicit bit from bit 126 to bit 55 since the
329 * ieee754dp_format code expects the mantissa to be
330 * 56 bits wide (53 + 3 rounding bits).
331 */
332 srl128(&hzm, &lzm, (126 - 55));
333
334 return ieee754dp_format(zs, ze, lzm);
273} 335}
274 336
275union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, 337union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
@@ -281,5 +343,5 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
281union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, 343union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
282 union ieee754dp y) 344 union ieee754dp y)
283{ 345{
284 return _dp_maddf(z, x, y, maddf_negate_product); 346 return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
285} 347}
diff --git a/arch/mips/math-emu/dp_rint.c b/arch/mips/math-emu/dp_rint.c
new file mode 100644
index 000000000000..c3b9077ff357
--- /dev/null
+++ b/arch/mips/math-emu/dp_rint.c
@@ -0,0 +1,89 @@
1/* IEEE754 floating point arithmetic
2 * double precision: common utilities
3 */
4/*
5 * MIPS floating point support
6 * Copyright (C) 1994-2000 Algorithmics Ltd.
7 * Copyright (C) 2017 Imagination Technologies, Ltd.
8 * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
9 *
10 * This program is free software; you can distribute it and/or modify it
11 * under the terms of the GNU General Public License (Version 2) as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program.
21 */
22
23#include "ieee754dp.h"
24
25union ieee754dp ieee754dp_rint(union ieee754dp x)
26{
27 union ieee754dp ret;
28 u64 residue;
29 int sticky;
30 int round;
31 int odd;
32
33 COMPXDP;
34
35 ieee754_clearcx();
36
37 EXPLODEXDP;
38 FLUSHXDP;
39
40 if (xc == IEEE754_CLASS_SNAN)
41 return ieee754dp_nanxcpt(x);
42
43 if ((xc == IEEE754_CLASS_QNAN) ||
44 (xc == IEEE754_CLASS_INF) ||
45 (xc == IEEE754_CLASS_ZERO))
46 return x;
47
48 if (xe >= DP_FBITS)
49 return x;
50
51 if (xe < -1) {
52 residue = xm;
53 round = 0;
54 sticky = residue != 0;
55 xm = 0;
56 } else {
57 residue = xm << (64 - DP_FBITS + xe);
58 round = (residue >> 63) != 0;
59 sticky = (residue << 1) != 0;
60 xm >>= DP_FBITS - xe;
61 }
62
63 odd = (xm & 0x1) != 0x0;
64
65 switch (ieee754_csr.rm) {
66 case FPU_CSR_RN: /* toward nearest */
67 if (round && (sticky || odd))
68 xm++;
69 break;
70 case FPU_CSR_RZ: /* toward zero */
71 break;
72 case FPU_CSR_RU: /* toward +infinity */
73 if ((round || sticky) && !xs)
74 xm++;
75 break;
76 case FPU_CSR_RD: /* toward -infinity */
77 if ((round || sticky) && xs)
78 xm++;
79 break;
80 }
81
82 if (round || sticky)
83 ieee754_setcx(IEEE754_INEXACT);
84
85 ret = ieee754dp_flong(xm);
86 DPSIGN(ret) = xs;
87
88 return ret;
89}
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
index d3be351aed15..92dc8fa565cb 100644
--- a/arch/mips/math-emu/ieee754.h
+++ b/arch/mips/math-emu/ieee754.h
@@ -67,6 +67,7 @@ union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y);
67union ieee754sp ieee754sp_fint(int x); 67union ieee754sp ieee754sp_fint(int x);
68union ieee754sp ieee754sp_flong(s64 x); 68union ieee754sp ieee754sp_flong(s64 x);
69union ieee754sp ieee754sp_fdp(union ieee754dp x); 69union ieee754sp ieee754sp_fdp(union ieee754dp x);
70union ieee754sp ieee754sp_rint(union ieee754sp x);
70 71
71int ieee754sp_tint(union ieee754sp x); 72int ieee754sp_tint(union ieee754sp x);
72s64 ieee754sp_tlong(union ieee754sp x); 73s64 ieee754sp_tlong(union ieee754sp x);
@@ -101,6 +102,7 @@ union ieee754dp ieee754dp_neg(union ieee754dp x);
101union ieee754dp ieee754dp_fint(int x); 102union ieee754dp ieee754dp_fint(int x);
102union ieee754dp ieee754dp_flong(s64 x); 103union ieee754dp ieee754dp_flong(s64 x);
103union ieee754dp ieee754dp_fsp(union ieee754sp x); 104union ieee754dp ieee754dp_fsp(union ieee754sp x);
105union ieee754dp ieee754dp_rint(union ieee754dp x);
104 106
105int ieee754dp_tint(union ieee754dp x); 107int ieee754dp_tint(union ieee754dp x);
106s64 ieee754dp_tlong(union ieee754dp x); 108s64 ieee754dp_tlong(union ieee754dp x);
diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h
index 8bc2f6963324..dd2071f430e0 100644
--- a/arch/mips/math-emu/ieee754int.h
+++ b/arch/mips/math-emu/ieee754int.h
@@ -26,6 +26,10 @@
26 26
27#define CLPAIR(x, y) ((x)*6+(y)) 27#define CLPAIR(x, y) ((x)*6+(y))
28 28
29enum maddf_flags {
30 MADDF_NEGATE_PRODUCT = 1 << 0,
31};
32
29static inline void ieee754_clearcx(void) 33static inline void ieee754_clearcx(void)
30{ 34{
31 ieee754_csr.cx = 0; 35 ieee754_csr.cx = 0;
diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h
index 8476067075fe..0f63e4202cff 100644
--- a/arch/mips/math-emu/ieee754sp.h
+++ b/arch/mips/math-emu/ieee754sp.h
@@ -45,6 +45,10 @@ static inline int ieee754sp_finite(union ieee754sp x)
45 return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS; 45 return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
46} 46}
47 47
48/* 64 bit right shift with rounding */
49#define XSPSRS64(v, rs) \
50 (((rs) >= 64) ? ((v) != 0) : ((v) >> (rs)) | ((v) << (64-(rs)) != 0))
51
48/* 3bit extended single precision sticky right shift */ 52/* 3bit extended single precision sticky right shift */
49#define XSPSRS(v, rs) \ 53#define XSPSRS(v, rs) \
50 ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0)) 54 ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0))
diff --git a/arch/mips/math-emu/me-debugfs.c b/arch/mips/math-emu/me-debugfs.c
index be650ed7db59..8c0ec154aecc 100644
--- a/arch/mips/math-emu/me-debugfs.c
+++ b/arch/mips/math-emu/me-debugfs.c
@@ -28,14 +28,190 @@ static int fpuemu_stat_get(void *data, u64 *val)
28} 28}
29DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n"); 29DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
30 30
31/*
32 * Used to obtain names for a debugfs instruction counter, given field name
33 * in fpuemustats structure. For example, for input "cmp_sueq_d", the output
34 * would be "cmp.sueq.d". This is needed since dots are not allowed to be
35 * used in structure field names, and are, on the other hand, desired to be
36 * used in debugfs item names to be clearly associated to corresponding
37 * MIPS FPU instructions.
38 */
39static void adjust_instruction_counter_name(char *out_name, char *in_name)
40{
41 int i = 0;
42
43 strcpy(out_name, in_name);
44 while (in_name[i] != '\0') {
45 if (out_name[i] == '_')
46 out_name[i] = '.';
47 i++;
48 }
49}
50
51static int fpuemustats_clear_show(struct seq_file *s, void *unused)
52{
53 __this_cpu_write((fpuemustats).emulated, 0);
54 __this_cpu_write((fpuemustats).loads, 0);
55 __this_cpu_write((fpuemustats).stores, 0);
56 __this_cpu_write((fpuemustats).branches, 0);
57 __this_cpu_write((fpuemustats).cp1ops, 0);
58 __this_cpu_write((fpuemustats).cp1xops, 0);
59 __this_cpu_write((fpuemustats).errors, 0);
60 __this_cpu_write((fpuemustats).ieee754_inexact, 0);
61 __this_cpu_write((fpuemustats).ieee754_underflow, 0);
62 __this_cpu_write((fpuemustats).ieee754_overflow, 0);
63 __this_cpu_write((fpuemustats).ieee754_zerodiv, 0);
64 __this_cpu_write((fpuemustats).ieee754_invalidop, 0);
65 __this_cpu_write((fpuemustats).ds_emul, 0);
66
67 __this_cpu_write((fpuemustats).abs_s, 0);
68 __this_cpu_write((fpuemustats).abs_d, 0);
69 __this_cpu_write((fpuemustats).add_s, 0);
70 __this_cpu_write((fpuemustats).add_d, 0);
71 __this_cpu_write((fpuemustats).bc1eqz, 0);
72 __this_cpu_write((fpuemustats).bc1nez, 0);
73 __this_cpu_write((fpuemustats).ceil_w_s, 0);
74 __this_cpu_write((fpuemustats).ceil_w_d, 0);
75 __this_cpu_write((fpuemustats).ceil_l_s, 0);
76 __this_cpu_write((fpuemustats).ceil_l_d, 0);
77 __this_cpu_write((fpuemustats).class_s, 0);
78 __this_cpu_write((fpuemustats).class_d, 0);
79 __this_cpu_write((fpuemustats).cmp_af_s, 0);
80 __this_cpu_write((fpuemustats).cmp_af_d, 0);
81 __this_cpu_write((fpuemustats).cmp_eq_s, 0);
82 __this_cpu_write((fpuemustats).cmp_eq_d, 0);
83 __this_cpu_write((fpuemustats).cmp_le_s, 0);
84 __this_cpu_write((fpuemustats).cmp_le_d, 0);
85 __this_cpu_write((fpuemustats).cmp_lt_s, 0);
86 __this_cpu_write((fpuemustats).cmp_lt_d, 0);
87 __this_cpu_write((fpuemustats).cmp_ne_s, 0);
88 __this_cpu_write((fpuemustats).cmp_ne_d, 0);
89 __this_cpu_write((fpuemustats).cmp_or_s, 0);
90 __this_cpu_write((fpuemustats).cmp_or_d, 0);
91 __this_cpu_write((fpuemustats).cmp_ueq_s, 0);
92 __this_cpu_write((fpuemustats).cmp_ueq_d, 0);
93 __this_cpu_write((fpuemustats).cmp_ule_s, 0);
94 __this_cpu_write((fpuemustats).cmp_ule_d, 0);
95 __this_cpu_write((fpuemustats).cmp_ult_s, 0);
96 __this_cpu_write((fpuemustats).cmp_ult_d, 0);
97 __this_cpu_write((fpuemustats).cmp_un_s, 0);
98 __this_cpu_write((fpuemustats).cmp_un_d, 0);
99 __this_cpu_write((fpuemustats).cmp_une_s, 0);
100 __this_cpu_write((fpuemustats).cmp_une_d, 0);
101 __this_cpu_write((fpuemustats).cmp_saf_s, 0);
102 __this_cpu_write((fpuemustats).cmp_saf_d, 0);
103 __this_cpu_write((fpuemustats).cmp_seq_s, 0);
104 __this_cpu_write((fpuemustats).cmp_seq_d, 0);
105 __this_cpu_write((fpuemustats).cmp_sle_s, 0);
106 __this_cpu_write((fpuemustats).cmp_sle_d, 0);
107 __this_cpu_write((fpuemustats).cmp_slt_s, 0);
108 __this_cpu_write((fpuemustats).cmp_slt_d, 0);
109 __this_cpu_write((fpuemustats).cmp_sne_s, 0);
110 __this_cpu_write((fpuemustats).cmp_sne_d, 0);
111 __this_cpu_write((fpuemustats).cmp_sor_s, 0);
112 __this_cpu_write((fpuemustats).cmp_sor_d, 0);
113 __this_cpu_write((fpuemustats).cmp_sueq_s, 0);
114 __this_cpu_write((fpuemustats).cmp_sueq_d, 0);
115 __this_cpu_write((fpuemustats).cmp_sule_s, 0);
116 __this_cpu_write((fpuemustats).cmp_sule_d, 0);
117 __this_cpu_write((fpuemustats).cmp_sult_s, 0);
118 __this_cpu_write((fpuemustats).cmp_sult_d, 0);
119 __this_cpu_write((fpuemustats).cmp_sun_s, 0);
120 __this_cpu_write((fpuemustats).cmp_sun_d, 0);
121 __this_cpu_write((fpuemustats).cmp_sune_s, 0);
122 __this_cpu_write((fpuemustats).cmp_sune_d, 0);
123 __this_cpu_write((fpuemustats).cvt_d_l, 0);
124 __this_cpu_write((fpuemustats).cvt_d_s, 0);
125 __this_cpu_write((fpuemustats).cvt_d_w, 0);
126 __this_cpu_write((fpuemustats).cvt_l_s, 0);
127 __this_cpu_write((fpuemustats).cvt_l_d, 0);
128 __this_cpu_write((fpuemustats).cvt_s_d, 0);
129 __this_cpu_write((fpuemustats).cvt_s_l, 0);
130 __this_cpu_write((fpuemustats).cvt_s_w, 0);
131 __this_cpu_write((fpuemustats).cvt_w_s, 0);
132 __this_cpu_write((fpuemustats).cvt_w_d, 0);
133 __this_cpu_write((fpuemustats).div_s, 0);
134 __this_cpu_write((fpuemustats).div_d, 0);
135 __this_cpu_write((fpuemustats).floor_w_s, 0);
136 __this_cpu_write((fpuemustats).floor_w_d, 0);
137 __this_cpu_write((fpuemustats).floor_l_s, 0);
138 __this_cpu_write((fpuemustats).floor_l_d, 0);
139 __this_cpu_write((fpuemustats).maddf_s, 0);
140 __this_cpu_write((fpuemustats).maddf_d, 0);
141 __this_cpu_write((fpuemustats).max_s, 0);
142 __this_cpu_write((fpuemustats).max_d, 0);
143 __this_cpu_write((fpuemustats).maxa_s, 0);
144 __this_cpu_write((fpuemustats).maxa_d, 0);
145 __this_cpu_write((fpuemustats).min_s, 0);
146 __this_cpu_write((fpuemustats).min_d, 0);
147 __this_cpu_write((fpuemustats).mina_s, 0);
148 __this_cpu_write((fpuemustats).mina_d, 0);
149 __this_cpu_write((fpuemustats).mov_s, 0);
150 __this_cpu_write((fpuemustats).mov_d, 0);
151 __this_cpu_write((fpuemustats).msubf_s, 0);
152 __this_cpu_write((fpuemustats).msubf_d, 0);
153 __this_cpu_write((fpuemustats).mul_s, 0);
154 __this_cpu_write((fpuemustats).mul_d, 0);
155 __this_cpu_write((fpuemustats).neg_s, 0);
156 __this_cpu_write((fpuemustats).neg_d, 0);
157 __this_cpu_write((fpuemustats).recip_s, 0);
158 __this_cpu_write((fpuemustats).recip_d, 0);
159 __this_cpu_write((fpuemustats).rint_s, 0);
160 __this_cpu_write((fpuemustats).rint_d, 0);
161 __this_cpu_write((fpuemustats).round_w_s, 0);
162 __this_cpu_write((fpuemustats).round_w_d, 0);
163 __this_cpu_write((fpuemustats).round_l_s, 0);
164 __this_cpu_write((fpuemustats).round_l_d, 0);
165 __this_cpu_write((fpuemustats).rsqrt_s, 0);
166 __this_cpu_write((fpuemustats).rsqrt_d, 0);
167 __this_cpu_write((fpuemustats).sel_s, 0);
168 __this_cpu_write((fpuemustats).sel_d, 0);
169 __this_cpu_write((fpuemustats).seleqz_s, 0);
170 __this_cpu_write((fpuemustats).seleqz_d, 0);
171 __this_cpu_write((fpuemustats).selnez_s, 0);
172 __this_cpu_write((fpuemustats).selnez_d, 0);
173 __this_cpu_write((fpuemustats).sqrt_s, 0);
174 __this_cpu_write((fpuemustats).sqrt_d, 0);
175 __this_cpu_write((fpuemustats).sub_s, 0);
176 __this_cpu_write((fpuemustats).sub_d, 0);
177 __this_cpu_write((fpuemustats).trunc_w_s, 0);
178 __this_cpu_write((fpuemustats).trunc_w_d, 0);
179 __this_cpu_write((fpuemustats).trunc_l_s, 0);
180 __this_cpu_write((fpuemustats).trunc_l_d, 0);
181
182 return 0;
183}
184
185static int fpuemustats_clear_open(struct inode *inode, struct file *file)
186{
187 return single_open(file, fpuemustats_clear_show, inode->i_private);
188}
189
190static const struct file_operations fpuemustats_clear_fops = {
191 .open = fpuemustats_clear_open,
192 .read = seq_read,
193 .llseek = seq_lseek,
194 .release = single_release,
195};
196
31static int __init debugfs_fpuemu(void) 197static int __init debugfs_fpuemu(void)
32{ 198{
33 struct dentry *d, *dir; 199 struct dentry *fpuemu_debugfs_base_dir;
200 struct dentry *fpuemu_debugfs_inst_dir;
201 struct dentry *d, *reset_file;
34 202
35 if (!mips_debugfs_dir) 203 if (!mips_debugfs_dir)
36 return -ENODEV; 204 return -ENODEV;
37 dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); 205
38 if (!dir) 206 fpuemu_debugfs_base_dir = debugfs_create_dir("fpuemustats",
207 mips_debugfs_dir);
208 if (!fpuemu_debugfs_base_dir)
209 return -ENOMEM;
210
211 reset_file = debugfs_create_file("fpuemustats_clear", 0444,
212 mips_debugfs_dir, NULL,
213 &fpuemustats_clear_fops);
214 if (!reset_file)
39 return -ENOMEM; 215 return -ENOMEM;
40 216
41#define FPU_EMU_STAT_OFFSET(m) \ 217#define FPU_EMU_STAT_OFFSET(m) \
@@ -43,7 +219,7 @@ static int __init debugfs_fpuemu(void)
43 219
44#define FPU_STAT_CREATE(m) \ 220#define FPU_STAT_CREATE(m) \
45do { \ 221do { \
46 d = debugfs_create_file(#m , S_IRUGO, dir, \ 222 d = debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \
47 (void *)FPU_EMU_STAT_OFFSET(m), \ 223 (void *)FPU_EMU_STAT_OFFSET(m), \
48 &fops_fpuemu_stat); \ 224 &fops_fpuemu_stat); \
49 if (!d) \ 225 if (!d) \
@@ -53,6 +229,7 @@ do { \
53 FPU_STAT_CREATE(emulated); 229 FPU_STAT_CREATE(emulated);
54 FPU_STAT_CREATE(loads); 230 FPU_STAT_CREATE(loads);
55 FPU_STAT_CREATE(stores); 231 FPU_STAT_CREATE(stores);
232 FPU_STAT_CREATE(branches);
56 FPU_STAT_CREATE(cp1ops); 233 FPU_STAT_CREATE(cp1ops);
57 FPU_STAT_CREATE(cp1xops); 234 FPU_STAT_CREATE(cp1xops);
58 FPU_STAT_CREATE(errors); 235 FPU_STAT_CREATE(errors);
@@ -63,6 +240,139 @@ do { \
63 FPU_STAT_CREATE(ieee754_invalidop); 240 FPU_STAT_CREATE(ieee754_invalidop);
64 FPU_STAT_CREATE(ds_emul); 241 FPU_STAT_CREATE(ds_emul);
65 242
243 fpuemu_debugfs_inst_dir = debugfs_create_dir("instructions",
244 fpuemu_debugfs_base_dir);
245 if (!fpuemu_debugfs_inst_dir)
246 return -ENOMEM;
247
248#define FPU_STAT_CREATE_EX(m) \
249do { \
250 char name[32]; \
251 \
252 adjust_instruction_counter_name(name, #m); \
253 \
254 d = debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \
255 (void *)FPU_EMU_STAT_OFFSET(m), \
256 &fops_fpuemu_stat); \
257 if (!d) \
258 return -ENOMEM; \
259} while (0)
260
261 FPU_STAT_CREATE_EX(abs_s);
262 FPU_STAT_CREATE_EX(abs_d);
263 FPU_STAT_CREATE_EX(add_s);
264 FPU_STAT_CREATE_EX(add_d);
265 FPU_STAT_CREATE_EX(bc1eqz);
266 FPU_STAT_CREATE_EX(bc1nez);
267 FPU_STAT_CREATE_EX(ceil_w_s);
268 FPU_STAT_CREATE_EX(ceil_w_d);
269 FPU_STAT_CREATE_EX(ceil_l_s);
270 FPU_STAT_CREATE_EX(ceil_l_d);
271 FPU_STAT_CREATE_EX(class_s);
272 FPU_STAT_CREATE_EX(class_d);
273 FPU_STAT_CREATE_EX(cmp_af_s);
274 FPU_STAT_CREATE_EX(cmp_af_d);
275 FPU_STAT_CREATE_EX(cmp_eq_s);
276 FPU_STAT_CREATE_EX(cmp_eq_d);
277 FPU_STAT_CREATE_EX(cmp_le_s);
278 FPU_STAT_CREATE_EX(cmp_le_d);
279 FPU_STAT_CREATE_EX(cmp_lt_s);
280 FPU_STAT_CREATE_EX(cmp_lt_d);
281 FPU_STAT_CREATE_EX(cmp_ne_s);
282 FPU_STAT_CREATE_EX(cmp_ne_d);
283 FPU_STAT_CREATE_EX(cmp_or_s);
284 FPU_STAT_CREATE_EX(cmp_or_d);
285 FPU_STAT_CREATE_EX(cmp_ueq_s);
286 FPU_STAT_CREATE_EX(cmp_ueq_d);
287 FPU_STAT_CREATE_EX(cmp_ule_s);
288 FPU_STAT_CREATE_EX(cmp_ule_d);
289 FPU_STAT_CREATE_EX(cmp_ult_s);
290 FPU_STAT_CREATE_EX(cmp_ult_d);
291 FPU_STAT_CREATE_EX(cmp_un_s);
292 FPU_STAT_CREATE_EX(cmp_un_d);
293 FPU_STAT_CREATE_EX(cmp_une_s);
294 FPU_STAT_CREATE_EX(cmp_une_d);
295 FPU_STAT_CREATE_EX(cmp_saf_s);
296 FPU_STAT_CREATE_EX(cmp_saf_d);
297 FPU_STAT_CREATE_EX(cmp_seq_s);
298 FPU_STAT_CREATE_EX(cmp_seq_d);
299 FPU_STAT_CREATE_EX(cmp_sle_s);
300 FPU_STAT_CREATE_EX(cmp_sle_d);
301 FPU_STAT_CREATE_EX(cmp_slt_s);
302 FPU_STAT_CREATE_EX(cmp_slt_d);
303 FPU_STAT_CREATE_EX(cmp_sne_s);
304 FPU_STAT_CREATE_EX(cmp_sne_d);
305 FPU_STAT_CREATE_EX(cmp_sor_s);
306 FPU_STAT_CREATE_EX(cmp_sor_d);
307 FPU_STAT_CREATE_EX(cmp_sueq_s);
308 FPU_STAT_CREATE_EX(cmp_sueq_d);
309 FPU_STAT_CREATE_EX(cmp_sule_s);
310 FPU_STAT_CREATE_EX(cmp_sule_d);
311 FPU_STAT_CREATE_EX(cmp_sult_s);
312 FPU_STAT_CREATE_EX(cmp_sult_d);
313 FPU_STAT_CREATE_EX(cmp_sun_s);
314 FPU_STAT_CREATE_EX(cmp_sun_d);
315 FPU_STAT_CREATE_EX(cmp_sune_s);
316 FPU_STAT_CREATE_EX(cmp_sune_d);
317 FPU_STAT_CREATE_EX(cvt_d_l);
318 FPU_STAT_CREATE_EX(cvt_d_s);
319 FPU_STAT_CREATE_EX(cvt_d_w);
320 FPU_STAT_CREATE_EX(cvt_l_s);
321 FPU_STAT_CREATE_EX(cvt_l_d);
322 FPU_STAT_CREATE_EX(cvt_s_d);
323 FPU_STAT_CREATE_EX(cvt_s_l);
324 FPU_STAT_CREATE_EX(cvt_s_w);
325 FPU_STAT_CREATE_EX(cvt_w_s);
326 FPU_STAT_CREATE_EX(cvt_w_d);
327 FPU_STAT_CREATE_EX(div_s);
328 FPU_STAT_CREATE_EX(div_d);
329 FPU_STAT_CREATE_EX(floor_w_s);
330 FPU_STAT_CREATE_EX(floor_w_d);
331 FPU_STAT_CREATE_EX(floor_l_s);
332 FPU_STAT_CREATE_EX(floor_l_d);
333 FPU_STAT_CREATE_EX(maddf_s);
334 FPU_STAT_CREATE_EX(maddf_d);
335 FPU_STAT_CREATE_EX(max_s);
336 FPU_STAT_CREATE_EX(max_d);
337 FPU_STAT_CREATE_EX(maxa_s);
338 FPU_STAT_CREATE_EX(maxa_d);
339 FPU_STAT_CREATE_EX(min_s);
340 FPU_STAT_CREATE_EX(min_d);
341 FPU_STAT_CREATE_EX(mina_s);
342 FPU_STAT_CREATE_EX(mina_d);
343 FPU_STAT_CREATE_EX(mov_s);
344 FPU_STAT_CREATE_EX(mov_d);
345 FPU_STAT_CREATE_EX(msubf_s);
346 FPU_STAT_CREATE_EX(msubf_d);
347 FPU_STAT_CREATE_EX(mul_s);
348 FPU_STAT_CREATE_EX(mul_d);
349 FPU_STAT_CREATE_EX(neg_s);
350 FPU_STAT_CREATE_EX(neg_d);
351 FPU_STAT_CREATE_EX(recip_s);
352 FPU_STAT_CREATE_EX(recip_d);
353 FPU_STAT_CREATE_EX(rint_s);
354 FPU_STAT_CREATE_EX(rint_d);
355 FPU_STAT_CREATE_EX(round_w_s);
356 FPU_STAT_CREATE_EX(round_w_d);
357 FPU_STAT_CREATE_EX(round_l_s);
358 FPU_STAT_CREATE_EX(round_l_d);
359 FPU_STAT_CREATE_EX(rsqrt_s);
360 FPU_STAT_CREATE_EX(rsqrt_d);
361 FPU_STAT_CREATE_EX(sel_s);
362 FPU_STAT_CREATE_EX(sel_d);
363 FPU_STAT_CREATE_EX(seleqz_s);
364 FPU_STAT_CREATE_EX(seleqz_d);
365 FPU_STAT_CREATE_EX(selnez_s);
366 FPU_STAT_CREATE_EX(selnez_d);
367 FPU_STAT_CREATE_EX(sqrt_s);
368 FPU_STAT_CREATE_EX(sqrt_d);
369 FPU_STAT_CREATE_EX(sub_s);
370 FPU_STAT_CREATE_EX(sub_d);
371 FPU_STAT_CREATE_EX(trunc_w_s);
372 FPU_STAT_CREATE_EX(trunc_w_d);
373 FPU_STAT_CREATE_EX(trunc_l_s);
374 FPU_STAT_CREATE_EX(trunc_l_d);
375
66 return 0; 376 return 0;
67} 377}
68arch_initcall(debugfs_fpuemu); 378arch_initcall(debugfs_fpuemu);
diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c
index 4d000844e48e..74a5a00d2f22 100644
--- a/arch/mips/math-emu/sp_fmax.c
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48 return ieee754sp_nanxcpt(x); 48 return ieee754sp_nanxcpt(x);
49 49
50 /* numbers are preferred to NaNs */ 50 /*
51 * Quiet NaN handling
52 */
53
54 /*
55 * The case of both inputs quiet NaNs
56 */
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 return x;
59
60 /*
61 * The cases of exactly one input quiet NaN (numbers
62 * are here preferred as returned values to NaNs)
63 */
51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 64 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 65 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 66 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 67 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55 return x; 68 return x;
56 69
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 70 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 71 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 72 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
80 return ys ? x : y; 92 return ys ? x : y;
81 93
82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 94 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83 if (xs == ys) 95 return ieee754sp_zero(xs & ys);
84 return x;
85 return ieee754sp_zero(1);
86 96
87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 97 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88 SPDNORMX; 98 SPDNORMX;
@@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
106 else if (xs < ys) 116 else if (xs < ys)
107 return x; 117 return x;
108 118
109 /* Compare exponent */ 119 /* Signs of inputs are equal, let's compare exponents */
110 if (xe > ye) 120 if (xs == 0) {
111 return x; 121 /* Inputs are both positive */
112 else if (xe < ye) 122 if (xe > ye)
113 return y; 123 return x;
124 else if (xe < ye)
125 return y;
126 } else {
127 /* Inputs are both negative */
128 if (xe > ye)
129 return y;
130 else if (xe < ye)
131 return x;
132 }
114 133
115 /* Compare mantissa */ 134 /* Signs and exponents of inputs are equal, let's compare mantissas */
135 if (xs == 0) {
136 /* Inputs are both positive, with equal signs and exponents */
137 if (xm <= ym)
138 return y;
139 return x;
140 }
141 /* Inputs are both negative, with equal signs and exponents */
116 if (xm <= ym) 142 if (xm <= ym)
117 return y; 143 return x;
118 return x; 144 return y;
119} 145}
120 146
121union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) 147union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
@@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
147 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 173 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148 return ieee754sp_nanxcpt(x); 174 return ieee754sp_nanxcpt(x);
149 175
150 /* numbers are preferred to NaNs */ 176 /*
177 * Quiet NaN handling
178 */
179
180 /*
181 * The case of both inputs quiet NaNs
182 */
183 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
184 return x;
185
186 /*
187 * The cases of exactly one input quiet NaN (numbers
188 * are here preferred as returned values to NaNs)
189 */
151 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 190 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 191 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 192 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 193 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155 return x; 194 return x;
156 195
157 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 196 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 197 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 198 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -164,6 +202,9 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
164 /* 202 /*
165 * Infinity and zero handling 203 * Infinity and zero handling
166 */ 204 */
205 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
206 return ieee754sp_inf(xs & ys);
207
167 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 208 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 209 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 210 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
@@ -171,7 +212,6 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
171 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 212 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172 return x; 213 return x;
173 214
174 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 215 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 216 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 217 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
@@ -180,9 +220,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
180 return y; 220 return y;
181 221
182 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 222 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183 if (xs == ys) 223 return ieee754sp_zero(xs & ys);
184 return x;
185 return ieee754sp_zero(1);
186 224
187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 225 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188 SPDNORMX; 226 SPDNORMX;
@@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
207 return y; 245 return y;
208 246
209 /* Compare mantissa */ 247 /* Compare mantissa */
210 if (xm <= ym) 248 if (xm < ym)
211 return y; 249 return y;
212 return x; 250 else if (xm > ym)
251 return x;
252 else if (xs == 0)
253 return x;
254 return y;
213} 255}
diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c
index 4eb1bb9e9dec..c51385f46b09 100644
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 47 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48 return ieee754sp_nanxcpt(x); 48 return ieee754sp_nanxcpt(x);
49 49
50 /* numbers are preferred to NaNs */ 50 /*
51 * Quiet NaN handling
52 */
53
54 /*
55 * The case of both inputs quiet NaNs
56 */
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 return x;
59
60 /*
61 * The cases of exactly one input quiet NaN (numbers
62 * are here preferred as returned values to NaNs)
63 */
51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 64 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 65 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 66 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 67 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55 return x; 68 return x;
56 69
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 70 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 71 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 72 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
80 return ys ? y : x; 92 return ys ? y : x;
81 93
82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 94 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83 if (xs == ys) 95 return ieee754sp_zero(xs | ys);
84 return x;
85 return ieee754sp_zero(1);
86 96
87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 97 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88 SPDNORMX; 98 SPDNORMX;
@@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
106 else if (xs < ys) 116 else if (xs < ys)
107 return y; 117 return y;
108 118
109 /* Compare exponent */ 119 /* Signs of inputs are the same, let's compare exponents */
110 if (xe > ye) 120 if (xs == 0) {
111 return y; 121 /* Inputs are both positive */
112 else if (xe < ye) 122 if (xe > ye)
113 return x; 123 return y;
124 else if (xe < ye)
125 return x;
126 } else {
127 /* Inputs are both negative */
128 if (xe > ye)
129 return x;
130 else if (xe < ye)
131 return y;
132 }
114 133
115 /* Compare mantissa */ 134 /* Signs and exponents of inputs are equal, let's compare mantissas */
135 if (xs == 0) {
136 /* Inputs are both positive, with equal signs and exponents */
137 if (xm <= ym)
138 return x;
139 return y;
140 }
141 /* Inputs are both negative, with equal signs and exponents */
116 if (xm <= ym) 142 if (xm <= ym)
117 return x; 143 return y;
118 return y; 144 return x;
119} 145}
120 146
121union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) 147union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
@@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
147 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 173 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148 return ieee754sp_nanxcpt(x); 174 return ieee754sp_nanxcpt(x);
149 175
150 /* numbers are preferred to NaNs */ 176 /*
177 * Quiet NaN handling
178 */
179
180 /*
181 * The case of both inputs quiet NaNs
182 */
183 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
184 return x;
185
186 /*
187 * The cases of exactly one input quiet NaN (numbers
188 * are here preferred as returned values to NaNs)
189 */
151 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 190 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 191 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 192 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 193 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155 return x; 194 return x;
156 195
157 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 196 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 197 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 198 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
@@ -164,25 +202,25 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
164 /* 202 /*
165 * Infinity and zero handling 203 * Infinity and zero handling
166 */ 204 */
205 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
206 return ieee754sp_inf(xs | ys);
207
167 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 208 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 209 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 210 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 211 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 212 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172 return x; 213 return y;
173 214
174 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 215 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 216 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 217 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 218 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 219 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180 return y; 220 return x;
181 221
182 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 222 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183 if (xs == ys) 223 return ieee754sp_zero(xs | ys);
184 return x;
185 return ieee754sp_zero(1);
186 224
187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 225 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188 SPDNORMX; 226 SPDNORMX;
@@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
207 return x; 245 return x;
208 246
209 /* Compare mantissa */ 247 /* Compare mantissa */
210 if (xm <= ym) 248 if (xm < ym)
249 return x;
250 else if (xm > ym)
251 return y;
252 else if (xs == 1)
211 return x; 253 return x;
212 return y; 254 return y;
213} 255}
diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c
index c91d5e5d9b5f..7195fe785d81 100644
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -14,9 +14,6 @@
14 14
15#include "ieee754sp.h" 15#include "ieee754sp.h"
16 16
17enum maddf_flags {
18 maddf_negate_product = 1 << 0,
19};
20 17
21static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, 18static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
22 union ieee754sp y, enum maddf_flags flags) 19 union ieee754sp y, enum maddf_flags flags)
@@ -24,14 +21,8 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
24 int re; 21 int re;
25 int rs; 22 int rs;
26 unsigned rm; 23 unsigned rm;
27 unsigned short lxm; 24 uint64_t rm64;
28 unsigned short hxm; 25 uint64_t zm64;
29 unsigned short lym;
30 unsigned short hym;
31 unsigned lrm;
32 unsigned hrm;
33 unsigned t;
34 unsigned at;
35 int s; 26 int s;
36 27
37 COMPXSP; 28 COMPXSP;
@@ -48,51 +39,35 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
48 39
49 ieee754_clearcx(); 40 ieee754_clearcx();
50 41
51 switch (zc) { 42 /*
52 case IEEE754_CLASS_SNAN: 43 * Handle the cases when at least one of x, y or z is a NaN.
53 ieee754_setcx(IEEE754_INVALID_OPERATION); 44 * Order of precedence is sNaN, qNaN and z, x, y.
45 */
46 if (zc == IEEE754_CLASS_SNAN)
54 return ieee754sp_nanxcpt(z); 47 return ieee754sp_nanxcpt(z);
55 case IEEE754_CLASS_DNORM: 48 if (xc == IEEE754_CLASS_SNAN)
56 SPDNORMZ; 49 return ieee754sp_nanxcpt(x);
57 /* QNAN and ZERO cases are handled separately below */ 50 if (yc == IEEE754_CLASS_SNAN)
58 }
59
60 switch (CLPAIR(xc, yc)) {
61 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
62 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
63 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
64 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
65 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
66 return ieee754sp_nanxcpt(y); 51 return ieee754sp_nanxcpt(y);
52 if (zc == IEEE754_CLASS_QNAN)
53 return z;
54 if (xc == IEEE754_CLASS_QNAN)
55 return x;
56 if (yc == IEEE754_CLASS_QNAN)
57 return y;
67 58
68 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 59 if (zc == IEEE754_CLASS_DNORM)
69 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 60 SPDNORMZ;
70 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 61 /* ZERO z cases are handled separately below */
71 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
72 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
73 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
74 return ieee754sp_nanxcpt(x);
75 62
76 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 63 switch (CLPAIR(xc, yc)) {
77 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
78 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
79 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
80 return y;
81 64
82 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
83 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
84 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
85 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
86 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
87 return x;
88 65
89 /* 66 /*
90 * Infinity handling 67 * Infinity handling
91 */ 68 */
92 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 69 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
93 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 70 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
94 if (zc == IEEE754_CLASS_QNAN)
95 return z;
96 ieee754_setcx(IEEE754_INVALID_OPERATION); 71 ieee754_setcx(IEEE754_INVALID_OPERATION);
97 return ieee754sp_indef(); 72 return ieee754sp_indef();
98 73
@@ -101,9 +76,27 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
101 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 76 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
102 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 77 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
103 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 78 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
104 if (zc == IEEE754_CLASS_QNAN) 79 if ((zc == IEEE754_CLASS_INF) &&
105 return z; 80 ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
106 return ieee754sp_inf(xs ^ ys); 81 ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
82 /*
83 * Cases of addition of infinities with opposite signs
84 * or subtraction of infinities with same signs.
85 */
86 ieee754_setcx(IEEE754_INVALID_OPERATION);
87 return ieee754sp_indef();
88 }
89 /*
90 * z is here either not an infinity, or an infinity having the
91 * same sign as product (x*y) (in case of MADDF.D instruction)
92 * or product -(x*y) (in MSUBF.D case). The result must be an
93 * infinity, and its sign is determined only by the value of
94 * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
95 */
96 if (flags & MADDF_NEGATE_PRODUCT)
97 return ieee754sp_inf(1 ^ (xs ^ ys));
98 else
99 return ieee754sp_inf(xs ^ ys);
107 100
108 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 101 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
109 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 102 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
@@ -112,32 +105,42 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
112 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 105 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
113 if (zc == IEEE754_CLASS_INF) 106 if (zc == IEEE754_CLASS_INF)
114 return ieee754sp_inf(zs); 107 return ieee754sp_inf(zs);
115 /* Multiplication is 0 so just return z */ 108 if (zc == IEEE754_CLASS_ZERO) {
109 /* Handle cases +0 + (-0) and similar ones. */
110 if ((!(flags & MADDF_NEGATE_PRODUCT)
111 && (zs == (xs ^ ys))) ||
112 ((flags & MADDF_NEGATE_PRODUCT)
113 && (zs != (xs ^ ys))))
114 /*
115 * Cases of addition of zeros of equal signs
116 * or subtraction of zeroes of opposite signs.
117 * The sign of the resulting zero is in any
118 * such case determined only by the sign of z.
119 */
120 return z;
121
122 return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
123 }
124 /* x*y is here 0, and z is not 0, so just return z */
116 return z; 125 return z;
117 126
118 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 127 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
119 SPDNORMX; 128 SPDNORMX;
120 129
121 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 130 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
122 if (zc == IEEE754_CLASS_QNAN) 131 if (zc == IEEE754_CLASS_INF)
123 return z;
124 else if (zc == IEEE754_CLASS_INF)
125 return ieee754sp_inf(zs); 132 return ieee754sp_inf(zs);
126 SPDNORMY; 133 SPDNORMY;
127 break; 134 break;
128 135
129 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 136 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
130 if (zc == IEEE754_CLASS_QNAN) 137 if (zc == IEEE754_CLASS_INF)
131 return z;
132 else if (zc == IEEE754_CLASS_INF)
133 return ieee754sp_inf(zs); 138 return ieee754sp_inf(zs);
134 SPDNORMX; 139 SPDNORMX;
135 break; 140 break;
136 141
137 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): 142 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
138 if (zc == IEEE754_CLASS_QNAN) 143 if (zc == IEEE754_CLASS_INF)
139 return z;
140 else if (zc == IEEE754_CLASS_INF)
141 return ieee754sp_inf(zs); 144 return ieee754sp_inf(zs);
142 /* fall through to real computations */ 145 /* fall through to real computations */
143 } 146 }
@@ -158,111 +161,93 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
158 161
159 re = xe + ye; 162 re = xe + ye;
160 rs = xs ^ ys; 163 rs = xs ^ ys;
161 if (flags & maddf_negate_product) 164 if (flags & MADDF_NEGATE_PRODUCT)
162 rs ^= 1; 165 rs ^= 1;
163 166
164 /* shunt to top of word */ 167 /* Multiple 24 bit xm and ym to give 48 bit results */
165 xm <<= 32 - (SP_FBITS + 1); 168 rm64 = (uint64_t)xm * ym;
166 ym <<= 32 - (SP_FBITS + 1);
167
168 /*
169 * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
170 */
171 lxm = xm & 0xffff;
172 hxm = xm >> 16;
173 lym = ym & 0xffff;
174 hym = ym >> 16;
175
176 lrm = lxm * lym; /* 16 * 16 => 32 */
177 hrm = hxm * hym; /* 16 * 16 => 32 */
178
179 t = lxm * hym; /* 16 * 16 => 32 */
180 at = lrm + (t << 16);
181 hrm += at < lrm;
182 lrm = at;
183 hrm = hrm + (t >> 16);
184 169
185 t = hxm * lym; /* 16 * 16 => 32 */ 170 /* Shunt to top of word */
186 at = lrm + (t << 16); 171 rm64 = rm64 << 16;
187 hrm += at < lrm;
188 lrm = at;
189 hrm = hrm + (t >> 16);
190 172
191 rm = hrm | (lrm != 0); 173 /* Put explicit bit at bit 62 if necessary */
192 174 if ((int64_t) rm64 < 0) {
193 /* 175 rm64 = rm64 >> 1;
194 * Sticky shift down to normal rounding precision.
195 */
196 if ((int) rm < 0) {
197 rm = (rm >> (32 - (SP_FBITS + 1 + 3))) |
198 ((rm << (SP_FBITS + 1 + 3)) != 0);
199 re++; 176 re++;
200 } else {
201 rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) |
202 ((rm << (SP_FBITS + 1 + 3 + 1)) != 0);
203 } 177 }
204 assert(rm & (SP_HIDDEN_BIT << 3));
205
206 if (zc == IEEE754_CLASS_ZERO)
207 return ieee754sp_format(rs, re, rm);
208 178
209 /* And now the addition */ 179 assert(rm64 & (1 << 62));
210 180
211 assert(zm & SP_HIDDEN_BIT); 181 if (zc == IEEE754_CLASS_ZERO) {
182 /*
183 * Move explicit bit from bit 62 to bit 26 since the
184 * ieee754sp_format code expects the mantissa to be
185 * 27 bits wide (24 + 3 rounding bits).
186 */
187 rm = XSPSRS64(rm64, (62 - 26));
188 return ieee754sp_format(rs, re, rm);
189 }
212 190
213 /* 191 /* Move explicit bit from bit 23 to bit 62 */
214 * Provide guard,round and stick bit space. 192 zm64 = (uint64_t)zm << (62 - 23);
215 */ 193 assert(zm64 & (1 << 62));
216 zm <<= 3;
217 194
195 /* Make the exponents the same */
218 if (ze > re) { 196 if (ze > re) {
219 /* 197 /*
220 * Have to shift r fraction right to align. 198 * Have to shift r fraction right to align.
221 */ 199 */
222 s = ze - re; 200 s = ze - re;
223 rm = XSPSRS(rm, s); 201 rm64 = XSPSRS64(rm64, s);
224 re += s; 202 re += s;
225 } else if (re > ze) { 203 } else if (re > ze) {
226 /* 204 /*
227 * Have to shift z fraction right to align. 205 * Have to shift z fraction right to align.
228 */ 206 */
229 s = re - ze; 207 s = re - ze;
230 zm = XSPSRS(zm, s); 208 zm64 = XSPSRS64(zm64, s);
231 ze += s; 209 ze += s;
232 } 210 }
233 assert(ze == re); 211 assert(ze == re);
234 assert(ze <= SP_EMAX); 212 assert(ze <= SP_EMAX);
235 213
214 /* Do the addition */
236 if (zs == rs) { 215 if (zs == rs) {
237 /* 216 /*
238 * Generate 28 bit result of adding two 27 bit numbers 217 * Generate 64 bit result by adding two 63 bit numbers
239 * leaving result in zm, zs and ze. 218 * leaving result in zm64, zs and ze.
240 */ 219 */
241 zm = zm + rm; 220 zm64 = zm64 + rm64;
242 221 if ((int64_t)zm64 < 0) { /* carry out */
243 if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */ 222 zm64 = XSPSRS1(zm64);
244 zm = XSPSRS1(zm);
245 ze++; 223 ze++;
246 } 224 }
247 } else { 225 } else {
248 if (zm >= rm) { 226 if (zm64 >= rm64) {
249 zm = zm - rm; 227 zm64 = zm64 - rm64;
250 } else { 228 } else {
251 zm = rm - zm; 229 zm64 = rm64 - zm64;
252 zs = rs; 230 zs = rs;
253 } 231 }
254 if (zm == 0) 232 if (zm64 == 0)
255 return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); 233 return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
256 234
257 /* 235 /*
258 * Normalize in extended single precision 236 * Put explicit bit at bit 62 if necessary.
259 */ 237 */
260 while ((zm >> (SP_MBITS + 3)) == 0) { 238 while ((zm64 >> 62) == 0) {
261 zm <<= 1; 239 zm64 <<= 1;
262 ze--; 240 ze--;
263 } 241 }
264
265 } 242 }
243
244 /*
245 * Move explicit bit from bit 62 to bit 26 since the
246 * ieee754sp_format code expects the mantissa to be
247 * 27 bits wide (24 + 3 rounding bits).
248 */
249 zm = XSPSRS64(zm64, (62 - 26));
250
266 return ieee754sp_format(zs, ze, zm); 251 return ieee754sp_format(zs, ze, zm);
267} 252}
268 253
@@ -275,5 +260,5 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x,
275union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, 260union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
276 union ieee754sp y) 261 union ieee754sp y)
277{ 262{
278 return _sp_maddf(z, x, y, maddf_negate_product); 263 return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
279} 264}
diff --git a/arch/mips/math-emu/sp_rint.c b/arch/mips/math-emu/sp_rint.c
new file mode 100644
index 000000000000..70765b17e196
--- /dev/null
+++ b/arch/mips/math-emu/sp_rint.c
@@ -0,0 +1,90 @@
1/* IEEE754 floating point arithmetic
2 * single precision
3 */
4/*
5 * MIPS floating point support
6 * Copyright (C) 1994-2000 Algorithmics Ltd.
7 * Copyright (C) 2017 Imagination Technologies, Ltd.
8 * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
9 *
10 * This program is free software; you can distribute it and/or modify it
11 * under the terms of the GNU General Public License (Version 2) as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program.
21 */
22
23#include "ieee754sp.h"
24
25union ieee754sp ieee754sp_rint(union ieee754sp x)
26{
27 union ieee754sp ret;
28 u32 residue;
29 int sticky;
30 int round;
31 int odd;
32
33 COMPXDP; /* <-- DP needed for 64-bit mantissa tmp */
34
35 ieee754_clearcx();
36
37 EXPLODEXSP;
38 FLUSHXSP;
39
40 if (xc == IEEE754_CLASS_SNAN)
41 return ieee754sp_nanxcpt(x);
42
43 if ((xc == IEEE754_CLASS_QNAN) ||
44 (xc == IEEE754_CLASS_INF) ||
45 (xc == IEEE754_CLASS_ZERO))
46 return x;
47
48 if (xe >= SP_FBITS)
49 return x;
50
51 if (xe < -1) {
52 residue = xm;
53 round = 0;
54 sticky = residue != 0;
55 xm = 0;
56 } else {
57 residue = xm << (xe + 1);
58 residue <<= 31 - SP_FBITS;
59 round = (residue >> 31) != 0;
60 sticky = (residue << 1) != 0;
61 xm >>= SP_FBITS - xe;
62 }
63
64 odd = (xm & 0x1) != 0x0;
65
66 switch (ieee754_csr.rm) {
67 case FPU_CSR_RN: /* toward nearest */
68 if (round && (sticky || odd))
69 xm++;
70 break;
71 case FPU_CSR_RZ: /* toward zero */
72 break;
73 case FPU_CSR_RU: /* toward +infinity */
74 if ((round || sticky) && !xs)
75 xm++;
76 break;
77 case FPU_CSR_RD: /* toward -infinity */
78 if ((round || sticky) && xs)
79 xm++;
80 break;
81 }
82
83 if (round || sticky)
84 ieee754_setcx(IEEE754_INEXACT);
85
86 ret = ieee754sp_flong(xm);
87 SPSIGN(ret) = xs;
88
89 return ret;
90}
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 81d6a15c93d0..6f534b209971 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -37,7 +37,7 @@
37#include <asm/cacheflush.h> /* for run_uncached() */ 37#include <asm/cacheflush.h> /* for run_uncached() */
38#include <asm/traps.h> 38#include <asm/traps.h>
39#include <asm/dma-coherence.h> 39#include <asm/dma-coherence.h>
40#include <asm/mips-cm.h> 40#include <asm/mips-cps.h>
41 41
42/* 42/*
43 * Bits describing what cache ops an SMP callback function may perform. 43 * Bits describing what cache ops an SMP callback function may perform.
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 899e46279902..44ac64d51827 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -20,6 +20,7 @@
20#include <asm/processor.h> 20#include <asm/processor.h>
21#include <asm/cpu.h> 21#include <asm/cpu.h>
22#include <asm/cpu-features.h> 22#include <asm/cpu-features.h>
23#include <asm/setup.h>
23 24
24/* Cache operations. */ 25/* Cache operations. */
25void (*flush_cache_all)(void); 26void (*flush_cache_all)(void);
@@ -44,7 +45,6 @@ void (*__flush_cache_vunmap)(void);
44 45
45void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); 46void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
46EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); 47EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
47void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
48 48
49/* MIPS specific cache operations */ 49/* MIPS specific cache operations */
50void (*flush_cache_sigtramp)(unsigned long addr); 50void (*flush_cache_sigtramp)(unsigned long addr);
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 8e78251eccc2..c01bd20d0208 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -127,23 +127,6 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
127 return gfp | dma_flag; 127 return gfp | dma_flag;
128} 128}
129 129
130static void *mips_dma_alloc_noncoherent(struct device *dev, size_t size,
131 dma_addr_t * dma_handle, gfp_t gfp)
132{
133 void *ret;
134
135 gfp = massage_gfp_flags(dev, gfp);
136
137 ret = (void *) __get_free_pages(gfp, get_order(size));
138
139 if (ret != NULL) {
140 memset(ret, 0, size);
141 *dma_handle = plat_map_dma_mem(dev, ret, size);
142 }
143
144 return ret;
145}
146
147static void *mips_dma_alloc_coherent(struct device *dev, size_t size, 130static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
148 dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) 131 dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
149{ 132{
@@ -151,13 +134,6 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
151 struct page *page = NULL; 134 struct page *page = NULL;
152 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; 135 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
153 136
154 /*
155 * XXX: seems like the coherent and non-coherent implementations could
156 * be consolidated.
157 */
158 if (attrs & DMA_ATTR_NON_CONSISTENT)
159 return mips_dma_alloc_noncoherent(dev, size, dma_handle, gfp);
160
161 gfp = massage_gfp_flags(dev, gfp); 137 gfp = massage_gfp_flags(dev, gfp);
162 138
163 if (IS_ENABLED(CONFIG_DMA_CMA) && gfpflags_allow_blocking(gfp)) 139 if (IS_ENABLED(CONFIG_DMA_CMA) && gfpflags_allow_blocking(gfp))
@@ -172,7 +148,8 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
172 ret = page_address(page); 148 ret = page_address(page);
173 memset(ret, 0, size); 149 memset(ret, 0, size);
174 *dma_handle = plat_map_dma_mem(dev, ret, size); 150 *dma_handle = plat_map_dma_mem(dev, ret, size);
175 if (!plat_device_is_coherent(dev)) { 151 if (!(attrs & DMA_ATTR_NON_CONSISTENT) &&
152 !plat_device_is_coherent(dev)) {
176 dma_cache_wback_inv((unsigned long) ret, size); 153 dma_cache_wback_inv((unsigned long) ret, size);
177 ret = UNCAC_ADDR(ret); 154 ret = UNCAC_ADDR(ret);
178 } 155 }
@@ -180,14 +157,6 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
180 return ret; 157 return ret;
181} 158}
182 159
183
184static void mips_dma_free_noncoherent(struct device *dev, size_t size,
185 void *vaddr, dma_addr_t dma_handle)
186{
187 plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
188 free_pages((unsigned long) vaddr, get_order(size));
189}
190
191static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, 160static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
192 dma_addr_t dma_handle, unsigned long attrs) 161 dma_addr_t dma_handle, unsigned long attrs)
193{ 162{
@@ -195,14 +164,9 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
195 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; 164 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
196 struct page *page = NULL; 165 struct page *page = NULL;
197 166
198 if (attrs & DMA_ATTR_NON_CONSISTENT) {
199 mips_dma_free_noncoherent(dev, size, vaddr, dma_handle);
200 return;
201 }
202
203 plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); 167 plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
204 168
205 if (!plat_device_is_coherent(dev)) 169 if (!(attrs & DMA_ATTR_NON_CONSISTENT) && !plat_device_is_coherent(dev))
206 addr = CAC_ADDR(addr); 170 addr = CAC_ADDR(addr);
207 171
208 page = virt_to_page((void *) addr); 172 page = virt_to_page((void *) addr);
@@ -409,12 +373,12 @@ static void mips_dma_sync_sg_for_device(struct device *dev,
409 } 373 }
410} 374}
411 375
412int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) 376static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
413{ 377{
414 return 0; 378 return 0;
415} 379}
416 380
417int mips_dma_supported(struct device *dev, u64 mask) 381static int mips_dma_supported(struct device *dev, u64 mask)
418{ 382{
419 return plat_dma_supported(dev, mask); 383 return plat_dma_supported(dev, mask);
420} 384}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 8ce2983a7015..5f6ea7d746de 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -31,6 +31,7 @@
31#include <linux/gfp.h> 31#include <linux/gfp.h>
32#include <linux/kcore.h> 32#include <linux/kcore.h>
33#include <linux/export.h> 33#include <linux/export.h>
34#include <linux/initrd.h>
34 35
35#include <asm/asm-offsets.h> 36#include <asm/asm-offsets.h>
36#include <asm/bootinfo.h> 37#include <asm/bootinfo.h>
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 28adeabe851f..33d3251ecd37 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -7,6 +7,7 @@
7 * written by Ralf Baechle <ralf@linux-mips.org> 7 * written by Ralf Baechle <ralf@linux-mips.org>
8 */ 8 */
9#include <linux/compiler.h> 9#include <linux/compiler.h>
10#include <linux/elf-randomize.h>
10#include <linux/errno.h> 11#include <linux/errno.h>
11#include <linux/mm.h> 12#include <linux/mm.h>
12#include <linux/mman.h> 13#include <linux/mman.h>
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index c909c3342729..acfb89273dad 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -14,7 +14,7 @@
14#include <asm/pgtable.h> 14#include <asm/pgtable.h>
15#include <asm/mmu_context.h> 15#include <asm/mmu_context.h>
16#include <asm/r4kcache.h> 16#include <asm/r4kcache.h>
17#include <asm/mips-cm.h> 17#include <asm/mips-cps.h>
18 18
19/* 19/*
20 * MIPS32/MIPS64 L2 cache handling 20 * MIPS32/MIPS64 L2 cache handling
@@ -63,34 +63,25 @@ static void mips_sc_prefetch_enable(void)
63 * prefetching for both code & data, for all ports. 63 * prefetching for both code & data, for all ports.
64 */ 64 */
65 pftctl = read_gcr_l2_pft_control(); 65 pftctl = read_gcr_l2_pft_control();
66 if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) { 66 if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT) {
67 pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; 67 pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK;
68 pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; 68 pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK;
69 pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; 69 pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN;
70 write_gcr_l2_pft_control(pftctl); 70 write_gcr_l2_pft_control(pftctl);
71 71
72 pftctl = read_gcr_l2_pft_control_b(); 72 set_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID |
73 pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; 73 CM_GCR_L2_PFT_CONTROL_B_CEN);
74 pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
75 write_gcr_l2_pft_control_b(pftctl);
76 } 74 }
77} 75}
78 76
79static void mips_sc_prefetch_disable(void) 77static void mips_sc_prefetch_disable(void)
80{ 78{
81 unsigned long pftctl;
82
83 if (mips_cm_revision() < CM_REV_CM2_5) 79 if (mips_cm_revision() < CM_REV_CM2_5)
84 return; 80 return;
85 81
86 pftctl = read_gcr_l2_pft_control(); 82 clear_gcr_l2_pft_control(CM_GCR_L2_PFT_CONTROL_PFTEN);
87 pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; 83 clear_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID |
88 write_gcr_l2_pft_control(pftctl); 84 CM_GCR_L2_PFT_CONTROL_B_CEN);
89
90 pftctl = read_gcr_l2_pft_control_b();
91 pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
92 pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
93 write_gcr_l2_pft_control_b(pftctl);
94} 85}
95 86
96static bool mips_sc_prefetch_is_enabled(void) 87static bool mips_sc_prefetch_is_enabled(void)
@@ -101,9 +92,9 @@ static bool mips_sc_prefetch_is_enabled(void)
101 return false; 92 return false;
102 93
103 pftctl = read_gcr_l2_pft_control(); 94 pftctl = read_gcr_l2_pft_control();
104 if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK)) 95 if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT))
105 return false; 96 return false;
106 return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK); 97 return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN);
107} 98}
108 99
109static struct bcache_ops mips_sc_ops = { 100static struct bcache_ops mips_sc_ops = {
@@ -160,21 +151,21 @@ static int __init mips_sc_probe_cm3(void)
160 unsigned long cfg = read_gcr_l2_config(); 151 unsigned long cfg = read_gcr_l2_config();
161 unsigned long sets, line_sz, assoc; 152 unsigned long sets, line_sz, assoc;
162 153
163 if (cfg & CM_GCR_L2_CONFIG_BYPASS_MSK) 154 if (cfg & CM_GCR_L2_CONFIG_BYPASS)
164 return 0; 155 return 0;
165 156
166 sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK; 157 sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE;
167 sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF; 158 sets >>= __ffs(CM_GCR_L2_CONFIG_SET_SIZE);
168 if (sets) 159 if (sets)
169 c->scache.sets = 64 << sets; 160 c->scache.sets = 64 << sets;
170 161
171 line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK; 162 line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE;
172 line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF; 163 line_sz >>= __ffs(CM_GCR_L2_CONFIG_LINE_SIZE);
173 if (line_sz) 164 if (line_sz)
174 c->scache.linesz = 2 << line_sz; 165 c->scache.linesz = 2 << line_sz;
175 166
176 assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK; 167 assoc = cfg & CM_GCR_L2_CONFIG_ASSOC;
177 assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF; 168 assoc >>= __ffs(CM_GCR_L2_CONFIG_ASSOC);
178 c->scache.ways = assoc + 1; 169 c->scache.ways = assoc + 1;
179 c->scache.waysize = c->scache.sets * c->scache.linesz; 170 c->scache.waysize = c->scache.sets * c->scache.linesz;
180 c->scache.waybit = __ffs(c->scache.waysize); 171 c->scache.waybit = __ffs(c->scache.waysize);
diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S
index 318855eb5f80..77db401fc620 100644
--- a/arch/mips/mm/tlbex-fault.S
+++ b/arch/mips/mm/tlbex-fault.S
@@ -12,14 +12,15 @@
12 12
13 .macro tlb_do_page_fault, write 13 .macro tlb_do_page_fault, write
14 NESTED(tlb_do_page_fault_\write, PT_SIZE, sp) 14 NESTED(tlb_do_page_fault_\write, PT_SIZE, sp)
15 SAVE_ALL 15 .cfi_signal_frame
16 SAVE_ALL docfi=1
16 MFC0 a2, CP0_BADVADDR 17 MFC0 a2, CP0_BADVADDR
17 KMODE 18 KMODE
18 move a0, sp 19 move a0, sp
19 REG_S a2, PT_BVADDR(sp) 20 REG_S a2, PT_BVADDR(sp)
20 li a1, \write 21 li a1, \write
21 PTR_LA ra, ret_from_exception 22 jal do_page_fault
22 j do_page_fault 23 j ret_from_exception
23 END(tlb_do_page_fault_\write) 24 END(tlb_do_page_fault_\write)
24 .endm 25 .endm
25 26
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 5aadc69c8ce3..79b9f2ad3ff5 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -2634,11 +2634,6 @@ void build_tlb_refill_handler(void)
2634#endif 2634#endif
2635 break; 2635 break;
2636 2636
2637 case CPU_R6000:
2638 case CPU_R6000A:
2639 panic("No R6000 TLB refill handler yet");
2640 break;
2641
2642 case CPU_R8000: 2637 case CPU_R8000:
2643 panic("No R8000 TLB refill handler yet"); 2638 panic("No R8000 TLB refill handler yet");
2644 break; 2639 break;
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index c398582c316f..a6699c15277d 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -18,7 +18,7 @@
18#include <asm/fw/fw.h> 18#include <asm/fw/fw.h>
19#include <asm/mips-boards/generic.h> 19#include <asm/mips-boards/generic.h>
20#include <asm/mips-boards/malta.h> 20#include <asm/mips-boards/malta.h>
21#include <asm/mips-cm.h> 21#include <asm/mips-cps.h>
22#include <asm/page.h> 22#include <asm/page.h>
23 23
24#define ROCIT_REG_BASE 0x1f403000 24#define ROCIT_REG_BASE 0x1f403000
@@ -236,7 +236,7 @@ static void __init remove_gic(void *fdt)
236 236
237 /* if we have a CM which reports a GIC is present, leave the DT alone */ 237 /* if we have a CM which reports a GIC is present, leave the DT alone */
238 err = mips_cm_probe(); 238 err = mips_cm_probe();
239 if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX_MSK)) 239 if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX))
240 return; 240 return;
241 241
242 if (malta_scon() == MIPS_REVISION_SCON_ROCIT) { 242 if (malta_scon() == MIPS_REVISION_SCON_ROCIT) {
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 0f3b881a3190..009f2918b320 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -21,8 +21,7 @@
21#include <asm/smp-ops.h> 21#include <asm/smp-ops.h>
22#include <asm/traps.h> 22#include <asm/traps.h>
23#include <asm/fw/fw.h> 23#include <asm/fw/fw.h>
24#include <asm/mips-cm.h> 24#include <asm/mips-cps.h>
25#include <asm/mips-cpc.h>
26#include <asm/mips-boards/generic.h> 25#include <asm/mips-boards/generic.h>
27#include <asm/mips-boards/malta.h> 26#include <asm/mips-boards/malta.h>
28 27
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index b0f9b188e833..a840e0c1642c 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -19,7 +19,6 @@
19#include <linux/smp.h> 19#include <linux/smp.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/irqchip/mips-gic.h>
23#include <linux/of_irq.h> 22#include <linux/of_irq.h>
24#include <linux/kernel_stat.h> 23#include <linux/kernel_stat.h>
25#include <linux/kernel.h> 24#include <linux/kernel.h>
@@ -29,9 +28,9 @@
29#include <asm/i8259.h> 28#include <asm/i8259.h>
30#include <asm/irq_cpu.h> 29#include <asm/irq_cpu.h>
31#include <asm/irq_regs.h> 30#include <asm/irq_regs.h>
32#include <asm/mips-cm.h>
33#include <asm/mips-boards/malta.h> 31#include <asm/mips-boards/malta.h>
34#include <asm/mips-boards/maltaint.h> 32#include <asm/mips-boards/maltaint.h>
33#include <asm/mips-cps.h>
35#include <asm/gt64120.h> 34#include <asm/gt64120.h>
36#include <asm/mips-boards/generic.h> 35#include <asm/mips-boards/generic.h>
37#include <asm/mips-boards/msc01_pci.h> 36#include <asm/mips-boards/msc01_pci.h>
@@ -215,7 +214,7 @@ void __init arch_init_irq(void)
215 msc_nr_irqs); 214 msc_nr_irqs);
216 } 215 }
217 216
218 if (gic_present) { 217 if (mips_gic_present()) {
219 corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; 218 corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
220 } else if (cpu_has_veic) { 219 } else if (cpu_has_veic) {
221 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); 220 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index a01d5debfcaf..de34adb76157 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -28,7 +28,7 @@
28 28
29#include <asm/fw/fw.h> 29#include <asm/fw/fw.h>
30#include <asm/mach-malta/malta-dtshim.h> 30#include <asm/mach-malta/malta-dtshim.h>
31#include <asm/mips-cm.h> 31#include <asm/mips-cps.h>
32#include <asm/mips-boards/generic.h> 32#include <asm/mips-boards/generic.h>
33#include <asm/mips-boards/malta.h> 33#include <asm/mips-boards/malta.h>
34#include <asm/mips-boards/maltaint.h> 34#include <asm/mips-boards/maltaint.h>
@@ -128,7 +128,7 @@ static int __init plat_enable_iocoherency(void)
128 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); 128 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
129 pr_info("Enabled Bonito IOBC coherency\n"); 129 pr_info("Enabled Bonito IOBC coherency\n");
130 } 130 }
131 } else if (mips_cm_numiocu() != 0) { 131 } else if (mips_cps_numiocu(0) != 0) {
132 /* Nothing special needs to be done to enable coherency */ 132 /* Nothing special needs to be done to enable coherency */
133 pr_info("CMP IOCU detected\n"); 133 pr_info("CMP IOCU detected\n");
134 cfg = __raw_readl((u32 *)CKSEG1ADDR(ROCIT_CONFIG_GEN0)); 134 cfg = __raw_readl((u32 *)CKSEG1ADDR(ROCIT_CONFIG_GEN0));
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index cea4ec909806..66c866740ff2 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -26,7 +26,6 @@
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/irqchip/mips-gic.h>
30#include <linux/timex.h> 29#include <linux/timex.h>
31#include <linux/mc146818rtc.h> 30#include <linux/mc146818rtc.h>
32 31
@@ -40,6 +39,7 @@
40#include <asm/time.h> 39#include <asm/time.h>
41#include <asm/mc146818-time.h> 40#include <asm/mc146818-time.h>
42#include <asm/msc01_ic.h> 41#include <asm/msc01_ic.h>
42#include <asm/mips-cps.h>
43 43
44#include <asm/mips-boards/generic.h> 44#include <asm/mips-boards/generic.h>
45#include <asm/mips-boards/maltaint.h> 45#include <asm/mips-boards/maltaint.h>
@@ -85,8 +85,8 @@ static void __init estimate_frequencies(void)
85 85
86 local_irq_save(flags); 86 local_irq_save(flags);
87 87
88 if (gic_present) 88 if (mips_gic_present())
89 gic_start_count(); 89 clear_gic_config(GIC_CONFIG_COUNTSTOP);
90 90
91 /* 91 /*
92 * Read counters exactly on rising edge of update flag. 92 * Read counters exactly on rising edge of update flag.
@@ -95,8 +95,8 @@ static void __init estimate_frequencies(void)
95 while (CMOS_READ(RTC_REG_A) & RTC_UIP); 95 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
96 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); 96 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
97 start = read_c0_count(); 97 start = read_c0_count();
98 if (gic_present) 98 if (mips_gic_present())
99 gicstart = gic_read_count(); 99 gicstart = read_gic_counter();
100 100
101 /* Wait for falling edge before reading RTC. */ 101 /* Wait for falling edge before reading RTC. */
102 while (CMOS_READ(RTC_REG_A) & RTC_UIP); 102 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
@@ -105,8 +105,8 @@ static void __init estimate_frequencies(void)
105 /* Read counters again exactly on rising edge of update flag. */ 105 /* Read counters again exactly on rising edge of update flag. */
106 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); 106 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
107 count = read_c0_count(); 107 count = read_c0_count();
108 if (gic_present) 108 if (mips_gic_present())
109 giccount = gic_read_count(); 109 giccount = read_gic_counter();
110 110
111 /* Wait for falling edge before reading RTC again. */ 111 /* Wait for falling edge before reading RTC again. */
112 while (CMOS_READ(RTC_REG_A) & RTC_UIP); 112 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
@@ -128,7 +128,7 @@ static void __init estimate_frequencies(void)
128 count /= secs; 128 count /= secs;
129 mips_hpt_frequency = count; 129 mips_hpt_frequency = count;
130 130
131 if (gic_present) { 131 if (mips_gic_present()) {
132 giccount = div_u64(giccount - gicstart, secs); 132 giccount = div_u64(giccount - gicstart, secs);
133 gic_frequency = giccount; 133 gic_frequency = giccount;
134 } 134 }
@@ -154,7 +154,7 @@ int get_c0_fdc_int(void)
154 154
155 if (cpu_has_veic) 155 if (cpu_has_veic)
156 return -1; 156 return -1;
157 else if (gic_present) 157 else if (mips_gic_present())
158 return gic_get_c0_fdc_int(); 158 return gic_get_c0_fdc_int();
159 else if (cp0_fdc_irq >= 0) 159 else if (cp0_fdc_irq >= 0)
160 return MIPS_CPU_IRQ_BASE + cp0_fdc_irq; 160 return MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
@@ -167,7 +167,7 @@ int get_c0_perfcount_int(void)
167 if (cpu_has_veic) { 167 if (cpu_has_veic) {
168 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); 168 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
169 mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; 169 mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
170 } else if (gic_present) { 170 } else if (mips_gic_present()) {
171 mips_cpu_perf_irq = gic_get_c0_perfcount_int(); 171 mips_cpu_perf_irq = gic_get_c0_perfcount_int();
172 } else if (cp0_perfcount_irq >= 0) { 172 } else if (cp0_perfcount_irq >= 0) {
173 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 173 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
@@ -184,7 +184,7 @@ unsigned int get_c0_compare_int(void)
184 if (cpu_has_veic) { 184 if (cpu_has_veic) {
185 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); 185 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
186 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; 186 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
187 } else if (gic_present) { 187 } else if (mips_gic_present()) {
188 mips_cpu_timer_irq = gic_get_c0_compare_int(); 188 mips_cpu_timer_irq = gic_get_c0_compare_int();
189 } else { 189 } else {
190 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 190 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
@@ -258,8 +258,7 @@ void __init plat_time_init(void)
258 setup_pit_timer(); 258 setup_pit_timer();
259#endif 259#endif
260 260
261#ifdef CONFIG_MIPS_GIC 261 if (mips_gic_present()) {
262 if (gic_present) {
263 freq = freqround(gic_frequency, 5000); 262 freq = freqround(gic_frequency, 5000);
264 printk("GIC frequency %d.%02d MHz\n", freq/1000000, 263 printk("GIC frequency %d.%02d MHz\n", freq/1000000,
265 (freq%1000000)*100/1000000); 264 (freq%1000000)*100/1000000);
@@ -268,5 +267,4 @@ void __init plat_time_init(void)
268 timer_probe(); 267 timer_probe();
269#endif 268#endif
270 } 269 }
271#endif
272} 270}
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index bddf1ef553a4..39a300bd6cc2 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -122,7 +122,7 @@ static void nlm_init_secondary(void)
122 int hwtid; 122 int hwtid;
123 123
124 hwtid = hard_smp_processor_id(); 124 hwtid = hard_smp_processor_id();
125 current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE; 125 cpu_set_core(&current_cpu_data, hwtid / NLM_THREADS_PER_CORE);
126 current_cpu_data.package = nlm_nodeid(); 126 current_cpu_data.package = nlm_nodeid();
127 nlm_percpu_init(hwtid); 127 nlm_percpu_init(hwtid);
128 nlm_smp_irq_init(hwtid); 128 nlm_smp_irq_init(hwtid);
@@ -147,7 +147,7 @@ unsigned long nlm_next_gp;
147unsigned long nlm_next_sp; 147unsigned long nlm_next_sp;
148static cpumask_t phys_cpu_present_mask; 148static cpumask_t phys_cpu_present_mask;
149 149
150void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) 150int nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
151{ 151{
152 uint64_t picbase; 152 uint64_t picbase;
153 int hwtid; 153 int hwtid;
@@ -161,6 +161,8 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
161 /* barrier for sp/gp store above */ 161 /* barrier for sp/gp store above */
162 __sync(); 162 __sync();
163 nlm_pic_send_ipi(picbase, hwtid, 1, 1); /* NMI */ 163 nlm_pic_send_ipi(picbase, hwtid, 1, 1); /* NMI */
164
165 return 0;
164} 166}
165 167
166void __init nlm_smp_setup(void) 168void __init nlm_smp_setup(void)
@@ -272,7 +274,7 @@ int nlm_wakeup_secondary_cpus(void)
272 return 0; 274 return 0;
273} 275}
274 276
275struct plat_smp_ops nlm_smp_ops = { 277const struct plat_smp_ops nlm_smp_ops = {
276 .send_ipi_single = nlm_send_ipi_single, 278 .send_ipi_single = nlm_send_ipi_single,
277 .send_ipi_mask = nlm_send_ipi_mask, 279 .send_ipi_mask = nlm_send_ipi_mask,
278 .init_secondary = nlm_init_secondary, 280 .init_secondary = nlm_init_secondary,
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index c57da6f13929..c3e4c18ef8d4 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -38,9 +38,9 @@ static int perfcount_irq;
38#ifdef CONFIG_MIPS_MT_SMP 38#ifdef CONFIG_MIPS_MT_SMP
39static int cpu_has_mipsmt_pertccounters; 39static int cpu_has_mipsmt_pertccounters;
40#define WHAT (MIPS_PERFCTRL_MT_EN_VPE | \ 40#define WHAT (MIPS_PERFCTRL_MT_EN_VPE | \
41 M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id)) 41 M_PERFCTL_VPEID(cpu_vpe_id(&current_cpu_data)))
42#define vpe_id() (cpu_has_mipsmt_pertccounters ? \ 42#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
43 0 : cpu_data[smp_processor_id()].vpe_id) 43 0 : cpu_vpe_id(&current_cpu_data))
44 44
45/* 45/*
46 * The number of bits to shift to convert between counters per core and 46 * The number of bits to shift to convert between counters per core and
diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c
index 72eb1a56c645..107d9f90d668 100644
--- a/arch/mips/paravirt/paravirt-smp.c
+++ b/arch/mips/paravirt/paravirt-smp.c
@@ -100,11 +100,12 @@ static void paravirt_smp_finish(void)
100 local_irq_enable(); 100 local_irq_enable();
101} 101}
102 102
103static void paravirt_boot_secondary(int cpu, struct task_struct *idle) 103static int paravirt_boot_secondary(int cpu, struct task_struct *idle)
104{ 104{
105 paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle); 105 paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle);
106 smp_wmb(); 106 smp_wmb();
107 paravirt_smp_sp[cpu] = __KSTK_TOS(idle); 107 paravirt_smp_sp[cpu] = __KSTK_TOS(idle);
108 return 0;
108} 109}
109 110
110static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id) 111static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id)
@@ -133,7 +134,7 @@ static void paravirt_prepare_cpus(unsigned int max_cpus)
133 } 134 }
134} 135}
135 136
136struct plat_smp_ops paravirt_smp_ops = { 137const struct plat_smp_ops paravirt_smp_ops = {
137 .send_ipi_single = paravirt_send_ipi_single, 138 .send_ipi_single = paravirt_send_ipi_single,
138 .send_ipi_mask = paravirt_send_ipi_mask, 139 .send_ipi_mask = paravirt_send_ipi_mask,
139 .init_secondary = paravirt_init_secondary, 140 .init_secondary = paravirt_init_secondary,
diff --git a/arch/mips/paravirt/setup.c b/arch/mips/paravirt/setup.c
index cb8448b373a7..d2ffec1409a7 100644
--- a/arch/mips/paravirt/setup.c
+++ b/arch/mips/paravirt/setup.c
@@ -14,7 +14,7 @@
14#include <asm/smp-ops.h> 14#include <asm/smp-ops.h>
15#include <asm/time.h> 15#include <asm/time.h>
16 16
17extern struct plat_smp_ops paravirt_smp_ops; 17extern const struct plat_smp_ops paravirt_smp_ops;
18 18
19const char *get_system_type(void) 19const char *get_system_type(void)
20{ 20{
diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c
index fc7726088103..0c65c38e05d6 100644
--- a/arch/mips/pci/pci-legacy.c
+++ b/arch/mips/pci/pci-legacy.c
@@ -139,7 +139,7 @@ void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node)
139 struct of_pci_range range; 139 struct of_pci_range range;
140 struct of_pci_range_parser parser; 140 struct of_pci_range_parser parser;
141 141
142 pr_info("PCI host bridge %s ranges:\n", node->full_name); 142 pr_info("PCI host bridge %pOF ranges:\n", node);
143 hose->of_node = node; 143 hose->of_node = node;
144 144
145 if (of_pci_range_parser_init(&parser, node)) 145 if (of_pci_range_parser_init(&parser, node))
diff --git a/arch/mips/pci/pci-malta.c b/arch/mips/pci/pci-malta.c
index cfbbc3e3e914..88e625fb3a47 100644
--- a/arch/mips/pci/pci-malta.c
+++ b/arch/mips/pci/pci-malta.c
@@ -27,7 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28 28
29#include <asm/gt64120.h> 29#include <asm/gt64120.h>
30#include <asm/mips-cm.h> 30#include <asm/mips-cps.h>
31#include <asm/mips-boards/generic.h> 31#include <asm/mips-boards/generic.h>
32#include <asm/mips-boards/bonito64.h> 32#include <asm/mips-boards/bonito64.h>
33#include <asm/mips-boards/msc01_pci.h> 33#include <asm/mips-boards/msc01_pci.h>
@@ -201,7 +201,7 @@ void __init mips_pcibios_init(void)
201 msc_mem_resource.start = start & mask; 201 msc_mem_resource.start = start & mask;
202 msc_mem_resource.end = (start & mask) | ~mask; 202 msc_mem_resource.end = (start & mask) | ~mask;
203 msc_controller.mem_offset = (start & mask) - (map & mask); 203 msc_controller.mem_offset = (start & mask) - (map & mask);
204 if (mips_cm_numiocu()) { 204 if (mips_cps_numiocu(0)) {
205 write_gcr_reg0_base(start); 205 write_gcr_reg0_base(start);
206 write_gcr_reg0_mask(mask | 206 write_gcr_reg0_mask(mask |
207 CM_GCR_REGn_MASK_CMTGT_IOCU0); 207 CM_GCR_REGn_MASK_CMTGT_IOCU0);
@@ -213,7 +213,7 @@ void __init mips_pcibios_init(void)
213 msc_io_resource.end = (map & mask) | ~mask; 213 msc_io_resource.end = (map & mask) | ~mask;
214 msc_controller.io_offset = 0; 214 msc_controller.io_offset = 0;
215 ioport_resource.end = ~mask; 215 ioport_resource.end = ~mask;
216 if (mips_cm_numiocu()) { 216 if (mips_cps_numiocu(0)) {
217 write_gcr_reg1_base(start); 217 write_gcr_reg1_base(start);
218 write_gcr_reg1_mask(mask | 218 write_gcr_reg1_mask(mask |
219 CM_GCR_REGn_MASK_CMTGT_IOCU0); 219 CM_GCR_REGn_MASK_CMTGT_IOCU0);
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c
index 628c5132b3d8..4e633c1e7ff3 100644
--- a/arch/mips/pci/pci-mt7620.c
+++ b/arch/mips/pci/pci-mt7620.c
@@ -291,7 +291,7 @@ static int mt7620_pci_probe(struct platform_device *pdev)
291 IORESOURCE_MEM, 1); 291 IORESOURCE_MEM, 1);
292 u32 val = 0; 292 u32 val = 0;
293 293
294 rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0"); 294 rstpcie0 = devm_reset_control_get_exclusive(&pdev->dev, "pcie0");
295 if (IS_ERR(rstpcie0)) 295 if (IS_ERR(rstpcie0))
296 return PTR_ERR(rstpcie0); 296 return PTR_ERR(rstpcie0);
297 297
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index 3520e9b414e7..04f8ea953297 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -207,8 +207,7 @@ static int rt3883_pci_irq_init(struct device *dev,
207 207
208 irq = irq_of_parse_and_map(rpc->intc_of_node, 0); 208 irq = irq_of_parse_and_map(rpc->intc_of_node, 0);
209 if (irq == 0) { 209 if (irq == 0) {
210 dev_err(dev, "%s has no IRQ", 210 dev_err(dev, "%pOF has no IRQ", rpc->intc_of_node);
211 of_node_full_name(rpc->intc_of_node));
212 return -EINVAL; 211 return -EINVAL;
213 } 212 }
214 213
@@ -438,8 +437,8 @@ static int rt3883_pci_probe(struct platform_device *pdev)
438 } 437 }
439 438
440 if (!rpc->intc_of_node) { 439 if (!rpc->intc_of_node) {
441 dev_err(dev, "%s has no %s child node", 440 dev_err(dev, "%pOF has no %s child node",
442 of_node_full_name(rpc->intc_of_node), 441 rpc->intc_of_node,
443 "interrupt controller"); 442 "interrupt controller");
444 return -EINVAL; 443 return -EINVAL;
445 } 444 }
@@ -454,8 +453,8 @@ static int rt3883_pci_probe(struct platform_device *pdev)
454 } 453 }
455 454
456 if (!rpc->pci_controller.of_node) { 455 if (!rpc->pci_controller.of_node) {
457 dev_err(dev, "%s has no %s child node", 456 dev_err(dev, "%pOF has no %s child node",
458 of_node_full_name(rpc->intc_of_node), 457 rpc->intc_of_node,
459 "PCI host bridge"); 458 "PCI host bridge");
460 err = -EINVAL; 459 err = -EINVAL;
461 goto err_put_intc_node; 460 goto err_put_intc_node;
diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c
index 1c91cad7988f..0b06c953d293 100644
--- a/arch/mips/pistachio/init.c
+++ b/arch/mips/pistachio/init.c
@@ -19,8 +19,7 @@
19#include <asm/dma-coherence.h> 19#include <asm/dma-coherence.h>
20#include <asm/fw/fw.h> 20#include <asm/fw/fw.h>
21#include <asm/mips-boards/generic.h> 21#include <asm/mips-boards/generic.h>
22#include <asm/mips-cm.h> 22#include <asm/mips-cps.h>
23#include <asm/mips-cpc.h>
24#include <asm/prom.h> 23#include <asm/prom.h>
25#include <asm/smp-ops.h> 24#include <asm/smp-ops.h>
26#include <asm/traps.h> 25#include <asm/traps.h>
diff --git a/arch/mips/pistachio/irq.c b/arch/mips/pistachio/irq.c
index 0a6b24c24652..709a8219073a 100644
--- a/arch/mips/pistachio/irq.c
+++ b/arch/mips/pistachio/irq.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/irqchip.h> 12#include <linux/irqchip.h>
13#include <linux/irqchip/mips-gic.h>
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15 14
16#include <asm/cpu-features.h> 15#include <asm/cpu-features.h>
diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c
index 17a0f1dec05b..8a6af9b76202 100644
--- a/arch/mips/pistachio/time.c
+++ b/arch/mips/pistachio/time.c
@@ -12,9 +12,9 @@
12#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
13#include <linux/clocksource.h> 13#include <linux/clocksource.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/irqchip/mips-gic.h>
16#include <linux/of.h> 15#include <linux/of.h>
17 16
17#include <asm/mips-cps.h>
18#include <asm/time.h> 18#include <asm/time.h>
19 19
20unsigned int get_c0_compare_int(void) 20unsigned int get_c0_compare_int(void)
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 710b04cf4851..b4627080b828 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -82,6 +82,16 @@ choice
82 depends on SOC_MT7620 82 depends on SOC_MT7620
83 select BUILTIN_DTB 83 select BUILTIN_DTB
84 84
85 config DTB_OMEGA2P
86 bool "Onion Omega2+"
87 depends on SOC_MT7620
88 select BUILTIN_DTB
89
90 config DTB_VOCORE2
91 bool "VoCore2"
92 depends on SOC_MT7620
93 select BUILTIN_DTB
94
85endchoice 95endchoice
86 96
87endif 97endif
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
index eb1c61917eb7..1b7df115eb60 100644
--- a/arch/mips/ralink/clk.c
+++ b/arch/mips/ralink/clk.c
@@ -53,6 +53,9 @@ EXPORT_SYMBOL_GPL(clk_disable);
53 53
54unsigned long clk_get_rate(struct clk *clk) 54unsigned long clk_get_rate(struct clk *clk)
55{ 55{
56 if (!clk)
57 return 0;
58
56 return clk->rate; 59 return clk->rate;
57} 60}
58EXPORT_SYMBOL_GPL(clk_get_rate); 61EXPORT_SYMBOL_GPL(clk_get_rate);
diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c
index 2058280450b5..bda576f2cad8 100644
--- a/arch/mips/ralink/irq-gic.c
+++ b/arch/mips/ralink/irq-gic.c
@@ -11,7 +11,7 @@
11 11
12#include <linux/of.h> 12#include <linux/of.h>
13#include <linux/irqchip.h> 13#include <linux/irqchip.h>
14#include <linux/irqchip/mips-gic.h> 14#include <asm/mips-cps.h>
15 15
16int get_c0_perfcount_int(void) 16int get_c0_perfcount_int(void)
17{ 17{
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index 0695c2d64e49..1b274742077d 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -12,8 +12,7 @@
12 12
13#include <asm/mipsregs.h> 13#include <asm/mipsregs.h>
14#include <asm/smp-ops.h> 14#include <asm/smp-ops.h>
15#include <asm/mips-cm.h> 15#include <asm/mips-cps.h>
16#include <asm/mips-cpc.h>
17#include <asm/mach-ralink/ralink_regs.h> 16#include <asm/mach-ralink/ralink_regs.h>
18#include <asm/mach-ralink/mt7621.h> 17#include <asm/mach-ralink/mt7621.h>
19 18
@@ -199,7 +198,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
199 mips_cm_probe(); 198 mips_cm_probe();
200 mips_cpc_probe(); 199 mips_cpc_probe();
201 200
202 if (mips_cm_numiocu()) { 201 if (mips_cps_numiocu(0)) {
203 /* 202 /*
204 * mips_cm_probe() wipes out bootloader 203 * mips_cm_probe() wipes out bootloader
205 * config for CM regions and we have to configure them 204 * config for CM regions and we have to configure them
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 4cd47d23d81a..545446dfe7fa 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -195,7 +195,7 @@ static void ip27_smp_finish(void)
195 * set sp to the kernel stack of the newly created idle process, gp to the proc 195 * set sp to the kernel stack of the newly created idle process, gp to the proc
196 * struct so that current_thread_info() will work. 196 * struct so that current_thread_info() will work.
197 */ 197 */
198static void ip27_boot_secondary(int cpu, struct task_struct *idle) 198static int ip27_boot_secondary(int cpu, struct task_struct *idle)
199{ 199{
200 unsigned long gp = (unsigned long)task_thread_info(idle); 200 unsigned long gp = (unsigned long)task_thread_info(idle);
201 unsigned long sp = __KSTK_TOS(idle); 201 unsigned long sp = __KSTK_TOS(idle);
@@ -203,6 +203,7 @@ static void ip27_boot_secondary(int cpu, struct task_struct *idle)
203 LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), 203 LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
204 (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), 204 (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
205 0, (void *) sp, (void *) gp); 205 0, (void *) sp, (void *) gp);
206 return 0;
206} 207}
207 208
208static void __init ip27_smp_setup(void) 209static void __init ip27_smp_setup(void)
@@ -231,7 +232,7 @@ static void __init ip27_prepare_cpus(unsigned int max_cpus)
231 /* We already did everything necessary earlier */ 232 /* We already did everything necessary earlier */
232} 233}
233 234
234struct plat_smp_ops ip27_smp_ops = { 235const struct plat_smp_ops ip27_smp_ops = {
235 .send_ipi_single = ip27_send_ipi_single, 236 .send_ipi_single = ip27_send_ipi_single,
236 .send_ipi_mask = ip27_send_ipi_mask, 237 .send_ipi_mask = ip27_send_ipi_mask,
237 .init_secondary = ip27_init_secondary, 238 .init_secondary = ip27_init_secondary,
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index d0e94ffcc1b8..90c9d1255ad7 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -117,7 +117,7 @@ static void bcm1480_smp_finish(void)
117 * Setup the PC, SP, and GP of a secondary processor and start it 117 * Setup the PC, SP, and GP of a secondary processor and start it
118 * running! 118 * running!
119 */ 119 */
120static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) 120static int bcm1480_boot_secondary(int cpu, struct task_struct *idle)
121{ 121{
122 int retval; 122 int retval;
123 123
@@ -126,6 +126,7 @@ static void bcm1480_boot_secondary(int cpu, struct task_struct *idle)
126 (unsigned long)task_thread_info(idle), 0); 126 (unsigned long)task_thread_info(idle), 0);
127 if (retval != 0) 127 if (retval != 0)
128 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); 128 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
129 return retval;
129} 130}
130 131
131/* 132/*
@@ -157,7 +158,7 @@ static void __init bcm1480_prepare_cpus(unsigned int max_cpus)
157{ 158{
158} 159}
159 160
160struct plat_smp_ops bcm1480_smp_ops = { 161const struct plat_smp_ops bcm1480_smp_ops = {
161 .send_ipi_single = bcm1480_send_ipi_single, 162 .send_ipi_single = bcm1480_send_ipi_single,
162 .send_ipi_mask = bcm1480_send_ipi_mask, 163 .send_ipi_mask = bcm1480_send_ipi_mask,
163 .init_secondary = bcm1480_init_secondary, 164 .init_secondary = bcm1480_init_secondary,
diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c
index c1a11a11db7f..115399202eab 100644
--- a/arch/mips/sibyte/common/cfe.c
+++ b/arch/mips/sibyte/common/cfe.c
@@ -229,8 +229,8 @@ static int __init initrd_setup(char *str)
229 229
230#endif 230#endif
231 231
232extern struct plat_smp_ops sb_smp_ops; 232extern const struct plat_smp_ops sb_smp_ops;
233extern struct plat_smp_ops bcm1480_smp_ops; 233extern const struct plat_smp_ops bcm1480_smp_ops;
234 234
235/* 235/*
236 * prom_init is called just after the cpu type is determined, from setup_arch() 236 * prom_init is called just after the cpu type is determined, from setup_arch()
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index 0a4a2c3982d8..5baabca52f25 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -106,7 +106,7 @@ static void sb1250_smp_finish(void)
106 * Setup the PC, SP, and GP of a secondary processor and start it 106 * Setup the PC, SP, and GP of a secondary processor and start it
107 * running! 107 * running!
108 */ 108 */
109static void sb1250_boot_secondary(int cpu, struct task_struct *idle) 109static int sb1250_boot_secondary(int cpu, struct task_struct *idle)
110{ 110{
111 int retval; 111 int retval;
112 112
@@ -115,6 +115,7 @@ static void sb1250_boot_secondary(int cpu, struct task_struct *idle)
115 (unsigned long)task_thread_info(idle), 0); 115 (unsigned long)task_thread_info(idle), 0);
116 if (retval != 0) 116 if (retval != 0)
117 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); 117 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
118 return retval;
118} 119}
119 120
120/* 121/*
@@ -146,7 +147,7 @@ static void __init sb1250_prepare_cpus(unsigned int max_cpus)
146{ 147{
147} 148}
148 149
149struct plat_smp_ops sb_smp_ops = { 150const struct plat_smp_ops sb_smp_ops = {
150 .send_ipi_single = sb1250_send_ipi_single, 151 .send_ipi_single = sb1250_send_ipi_single,
151 .send_ipi_mask = sb1250_send_ipi_mask, 152 .send_ipi_mask = sb1250_send_ipi_mask,
152 .init_secondary = sb1250_init_secondary, 153 .init_secondary = sb1250_init_secondary,
diff --git a/arch/mips/tools/generic-board-config.sh b/arch/mips/tools/generic-board-config.sh
new file mode 100755
index 000000000000..5c4f93687039
--- /dev/null
+++ b/arch/mips/tools/generic-board-config.sh
@@ -0,0 +1,90 @@
1#!/bin/sh
2#
3# Copyright (C) 2017 Imagination Technologies
4# Author: Paul Burton <paul.burton@imgtec.com>
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the
8# Free Software Foundation; either version 2 of the License, or (at your
9# option) any later version.
10#
11# This script merges configuration fragments for boards supported by the
12# generic MIPS kernel. It checks each for requirements specified using
13# formatted comments, and then calls merge_config.sh to merge those
14# fragments which have no unmet requirements.
15#
16# An example of requirements in your board config fragment might be:
17#
18# # require CONFIG_CPU_MIPS32_R2=y
19# # require CONFIG_CPU_LITTLE_ENDIAN=y
20#
21# This would mean that your board is only included in kernels which are
22# configured for little endian MIPS32r2 CPUs, and not for example in kernels
23# configured for 64 bit or big endian systems.
24#
25
26srctree="$1"
27objtree="$2"
28ref_cfg="$3"
29cfg="$4"
30boards_origin="$5"
31shift 5
32
33cd "${srctree}"
34
35# Only print Skipping... lines if the user explicitly specified BOARDS=. In the
36# general case it only serves to obscure the useful output about what actually
37# was included.
38case ${boards_origin} in
39"command line")
40 print_skipped=1
41 ;;
42environment*)
43 print_skipped=1
44 ;;
45*)
46 print_skipped=0
47 ;;
48esac
49
50for board in $@; do
51 board_cfg="arch/mips/configs/generic/board-${board}.config"
52 if [ ! -f "${board_cfg}" ]; then
53 echo "WARNING: Board config '${board_cfg}' not found"
54 continue
55 fi
56
57 # For each line beginning with # require, cut out the field following
58 # it & search for that in the reference config file. If the requirement
59 # is not found then the subshell will exit with code 1, and we'll
60 # continue on to the next board.
61 grep -E '^# require ' "${board_cfg}" | \
62 cut -d' ' -f 3- | \
63 while read req; do
64 case ${req} in
65 *=y)
66 # If we require something =y then we check that a line
67 # containing it is present in the reference config.
68 grep -Eq "^${req}\$" "${ref_cfg}" && continue
69 ;;
70 *=n)
71 # If we require something =n then we just invert that
72 # check, considering the requirement met if there isn't
73 # a line containing the value =y in the reference
74 # config.
75 grep -Eq "^${req/%=n/=y}\$" "${ref_cfg}" || continue
76 ;;
77 *)
78 echo "WARNING: Unhandled requirement '${req}'"
79 ;;
80 esac
81
82 [ ${print_skipped} -eq 1 ] && echo "Skipping ${board_cfg}"
83 exit 1
84 done || continue
85
86 # Merge this board config fragment into our final config file
87 ./scripts/kconfig/merge_config.sh \
88 -m -O ${objtree} ${cfg} ${board_cfg} \
89 | grep -Ev '^(#|Using)'
90done
diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
index e2690d7ca4dd..e22b422f282c 100644
--- a/arch/mips/vdso/gettimeofday.c
+++ b/arch/mips/vdso/gettimeofday.c
@@ -11,12 +11,10 @@
11#include "vdso.h" 11#include "vdso.h"
12 12
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/irqchip/mips-gic.h>
15#include <linux/time.h> 14#include <linux/time.h>
16 15
17#include <asm/clocksource.h> 16#include <asm/clocksource.h>
18#include <asm/io.h> 17#include <asm/io.h>
19#include <asm/mips-cm.h>
20#include <asm/unistd.h> 18#include <asm/unistd.h>
21#include <asm/vdso.h> 19#include <asm/vdso.h>
22 20
@@ -126,9 +124,9 @@ static __always_inline u64 read_gic_count(const union mips_vdso_data *data)
126 u32 hi, hi2, lo; 124 u32 hi, hi2, lo;
127 125
128 do { 126 do {
129 hi = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS); 127 hi = __raw_readl(gic + sizeof(lo));
130 lo = __raw_readl(gic + GIC_UMV_SH_COUNTER_31_00_OFS); 128 lo = __raw_readl(gic);
131 hi2 = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS); 129 hi2 = __raw_readl(gic + sizeof(lo));
132 } while (hi2 != hi); 130 } while (hi2 != hi);
133 131
134 return (((u64)hi) << 32) + lo; 132 return (((u64)hi) << 32) + lo;
diff --git a/arch/mips/vdso/sigreturn.S b/arch/mips/vdso/sigreturn.S
index 715bf5993529..30c6219912ac 100644
--- a/arch/mips/vdso/sigreturn.S
+++ b/arch/mips/vdso/sigreturn.S
@@ -19,31 +19,21 @@
19 .cfi_sections .debug_frame 19 .cfi_sections .debug_frame
20 20
21LEAF(__vdso_rt_sigreturn) 21LEAF(__vdso_rt_sigreturn)
22 .cfi_startproc
23 .frame sp, 0, ra
24 .mask 0x00000000, 0
25 .fmask 0x00000000, 0
26 .cfi_signal_frame 22 .cfi_signal_frame
27 23
28 li v0, __NR_rt_sigreturn 24 li v0, __NR_rt_sigreturn
29 syscall 25 syscall
30 26
31 .cfi_endproc
32 END(__vdso_rt_sigreturn) 27 END(__vdso_rt_sigreturn)
33 28
34#if _MIPS_SIM == _MIPS_SIM_ABI32 29#if _MIPS_SIM == _MIPS_SIM_ABI32
35 30
36LEAF(__vdso_sigreturn) 31LEAF(__vdso_sigreturn)
37 .cfi_startproc
38 .frame sp, 0, ra
39 .mask 0x00000000, 0
40 .fmask 0x00000000, 0
41 .cfi_signal_frame 32 .cfi_signal_frame
42 33
43 li v0, __NR_sigreturn 34 li v0, __NR_sigreturn
44 syscall 35 syscall
45 36
46 .cfi_endproc
47 END(__vdso_sigreturn) 37 END(__vdso_sigreturn)
48 38
49#endif 39#endif
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c
index 17b861ea2626..ae3167c28b12 100644
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -10,25 +10,45 @@
10#include <linux/cpu.h> 10#include <linux/cpu.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/irqchip/mips-gic.h>
14#include <linux/notifier.h> 13#include <linux/notifier.h>
15#include <linux/of_irq.h> 14#include <linux/of_irq.h>
16#include <linux/percpu.h> 15#include <linux/percpu.h>
17#include <linux/smp.h> 16#include <linux/smp.h>
18#include <linux/time.h> 17#include <linux/time.h>
18#include <asm/mips-cps.h>
19 19
20static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); 20static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
21static int gic_timer_irq; 21static int gic_timer_irq;
22static unsigned int gic_frequency; 22static unsigned int gic_frequency;
23 23
24static u64 notrace gic_read_count(void)
25{
26 unsigned int hi, hi2, lo;
27
28 if (mips_cm_is64)
29 return read_gic_counter();
30
31 do {
32 hi = read_gic_counter_32h();
33 lo = read_gic_counter_32l();
34 hi2 = read_gic_counter_32h();
35 } while (hi2 != hi);
36
37 return (((u64) hi) << 32) + lo;
38}
39
24static int gic_next_event(unsigned long delta, struct clock_event_device *evt) 40static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
25{ 41{
42 unsigned long flags;
26 u64 cnt; 43 u64 cnt;
27 int res; 44 int res;
28 45
29 cnt = gic_read_count(); 46 cnt = gic_read_count();
30 cnt += (u64)delta; 47 cnt += (u64)delta;
31 gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); 48 local_irq_save(flags);
49 write_gic_vl_other(mips_cm_vp_id(cpumask_first(evt->cpumask)));
50 write_gic_vo_compare(cnt);
51 local_irq_restore(flags);
32 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; 52 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
33 return res; 53 return res;
34} 54}
@@ -37,7 +57,7 @@ static irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
37{ 57{
38 struct clock_event_device *cd = dev_id; 58 struct clock_event_device *cd = dev_id;
39 59
40 gic_write_compare(gic_read_compare()); 60 write_gic_vl_compare(read_gic_vl_compare());
41 cd->event_handler(cd); 61 cd->event_handler(cd);
42 return IRQ_HANDLED; 62 return IRQ_HANDLED;
43} 63}
@@ -139,10 +159,15 @@ static struct clocksource gic_clocksource = {
139 159
140static int __init __gic_clocksource_init(void) 160static int __init __gic_clocksource_init(void)
141{ 161{
162 unsigned int count_width;
142 int ret; 163 int ret;
143 164
144 /* Set clocksource mask. */ 165 /* Set clocksource mask. */
145 gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); 166 count_width = read_gic_config() & GIC_CONFIG_COUNTBITS;
167 count_width >>= __fls(GIC_CONFIG_COUNTBITS);
168 count_width *= 4;
169 count_width += 32;
170 gic_clocksource.mask = CLOCKSOURCE_MASK(count_width);
146 171
147 /* Calculate a somewhat reasonable rating value. */ 172 /* Calculate a somewhat reasonable rating value. */
148 gic_clocksource.rating = 200 + gic_frequency / 10000000; 173 gic_clocksource.rating = 200 + gic_frequency / 10000000;
@@ -159,7 +184,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
159 struct clk *clk; 184 struct clk *clk;
160 int ret; 185 int ret;
161 186
162 if (!gic_present || !node->parent || 187 if (!mips_gic_present() || !node->parent ||
163 !of_device_is_compatible(node->parent, "mti,gic")) { 188 !of_device_is_compatible(node->parent, "mti,gic")) {
164 pr_warn("No DT definition for the mips gic driver\n"); 189 pr_warn("No DT definition for the mips gic driver\n");
165 return -ENXIO; 190 return -ENXIO;
@@ -197,7 +222,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
197 } 222 }
198 223
199 /* And finally start the counter */ 224 /* And finally start the counter */
200 gic_start_count(); 225 clear_gic_config(GIC_CONFIG_COUNTSTOP);
201 226
202 return 0; 227 return 0;
203} 228}
diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c
index 12b9145913de..72b5e47286b4 100644
--- a/drivers/cpuidle/cpuidle-cps.c
+++ b/drivers/cpuidle/cpuidle-cps.c
@@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev,
37 * TODO: don't treat core 0 specially, just prevent the final core 37 * TODO: don't treat core 0 specially, just prevent the final core
38 * TODO: remap interrupt affinity temporarily 38 * TODO: remap interrupt affinity temporarily
39 */ 39 */
40 if (!cpu_data[dev->cpu].core && (index > STATE_NC_WAIT)) 40 if (cpus_are_siblings(0, dev->cpu) && (index > STATE_NC_WAIT))
41 index = STATE_NC_WAIT; 41 index = STATE_NC_WAIT;
42 42
43 /* Select the appropriate cps_pm_state */ 43 /* Select the appropriate cps_pm_state */
diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c
index 14461cbfab2f..66f97fde13d8 100644
--- a/drivers/irqchip/irq-mips-cpu.c
+++ b/drivers/irqchip/irq-mips-cpu.c
@@ -101,7 +101,7 @@ static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu)
101 local_irq_save(flags); 101 local_irq_save(flags);
102 102
103 /* We can only send IPIs to VPEs within the local core */ 103 /* We can only send IPIs to VPEs within the local core */
104 WARN_ON(cpu_data[cpu].core != current_cpu_data.core); 104 WARN_ON(!cpus_are_siblings(smp_processor_id(), cpu));
105 105
106 vpflags = dvpe(); 106 vpflags = dvpe();
107 settc(cpu_vpe_id(&cpu_data[cpu])); 107 settc(cpu_vpe_id(&cpu_data[cpu]));
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index b3a60da088db..6e52a88bbd9e 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -12,27 +12,38 @@
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/irqchip.h> 14#include <linux/irqchip.h>
15#include <linux/irqchip/mips-gic.h>
16#include <linux/of_address.h> 15#include <linux/of_address.h>
16#include <linux/percpu.h>
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/smp.h> 18#include <linux/smp.h>
19 19
20#include <asm/mips-cm.h> 20#include <asm/mips-cps.h>
21#include <asm/setup.h> 21#include <asm/setup.h>
22#include <asm/traps.h> 22#include <asm/traps.h>
23 23
24#include <dt-bindings/interrupt-controller/mips-gic.h> 24#include <dt-bindings/interrupt-controller/mips-gic.h>
25 25
26unsigned int gic_present; 26#define GIC_MAX_INTRS 256
27#define GIC_MAX_LONGS BITS_TO_LONGS(GIC_MAX_INTRS)
27 28
28struct gic_pcpu_mask { 29/* Add 2 to convert GIC CPU pin to core interrupt */
29 DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS); 30#define GIC_CPU_PIN_OFFSET 2
30}; 31
32/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
33#define GIC_PIN_TO_VEC_OFFSET 1
34
35/* Convert between local/shared IRQ number and GIC HW IRQ number. */
36#define GIC_LOCAL_HWIRQ_BASE 0
37#define GIC_LOCAL_TO_HWIRQ(x) (GIC_LOCAL_HWIRQ_BASE + (x))
38#define GIC_HWIRQ_TO_LOCAL(x) ((x) - GIC_LOCAL_HWIRQ_BASE)
39#define GIC_SHARED_HWIRQ_BASE GIC_NUM_LOCAL_INTRS
40#define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x))
41#define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE)
42
43void __iomem *mips_gic_base;
31 44
32static unsigned long __gic_base_addr; 45DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
33 46
34static void __iomem *gic_base;
35static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
36static DEFINE_SPINLOCK(gic_lock); 47static DEFINE_SPINLOCK(gic_lock);
37static struct irq_domain *gic_irq_domain; 48static struct irq_domain *gic_irq_domain;
38static struct irq_domain *gic_ipi_domain; 49static struct irq_domain *gic_ipi_domain;
@@ -44,202 +55,13 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
44DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS); 55DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
45DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS); 56DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
46 57
47static void __gic_irq_dispatch(void); 58static void gic_clear_pcpu_masks(unsigned int intr)
48
49static inline u32 gic_read32(unsigned int reg)
50{
51 return __raw_readl(gic_base + reg);
52}
53
54static inline u64 gic_read64(unsigned int reg)
55{
56 return __raw_readq(gic_base + reg);
57}
58
59static inline unsigned long gic_read(unsigned int reg)
60{
61 if (!mips_cm_is64)
62 return gic_read32(reg);
63 else
64 return gic_read64(reg);
65}
66
67static inline void gic_write32(unsigned int reg, u32 val)
68{
69 return __raw_writel(val, gic_base + reg);
70}
71
72static inline void gic_write64(unsigned int reg, u64 val)
73{
74 return __raw_writeq(val, gic_base + reg);
75}
76
77static inline void gic_write(unsigned int reg, unsigned long val)
78{
79 if (!mips_cm_is64)
80 return gic_write32(reg, (u32)val);
81 else
82 return gic_write64(reg, (u64)val);
83}
84
85static inline void gic_update_bits(unsigned int reg, unsigned long mask,
86 unsigned long val)
87{
88 unsigned long regval;
89
90 regval = gic_read(reg);
91 regval &= ~mask;
92 regval |= val;
93 gic_write(reg, regval);
94}
95
96static inline void gic_reset_mask(unsigned int intr)
97{
98 gic_write(GIC_REG(SHARED, GIC_SH_RMASK) + GIC_INTR_OFS(intr),
99 1ul << GIC_INTR_BIT(intr));
100}
101
102static inline void gic_set_mask(unsigned int intr)
103{
104 gic_write(GIC_REG(SHARED, GIC_SH_SMASK) + GIC_INTR_OFS(intr),
105 1ul << GIC_INTR_BIT(intr));
106}
107
108static inline void gic_set_polarity(unsigned int intr, unsigned int pol)
109{
110 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) +
111 GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
112 (unsigned long)pol << GIC_INTR_BIT(intr));
113}
114
115static inline void gic_set_trigger(unsigned int intr, unsigned int trig)
116{
117 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
118 GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
119 (unsigned long)trig << GIC_INTR_BIT(intr));
120}
121
122static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual)
123{
124 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr),
125 1ul << GIC_INTR_BIT(intr),
126 (unsigned long)dual << GIC_INTR_BIT(intr));
127}
128
129static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)
130{
131 gic_write32(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +
132 GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin);
133}
134
135static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
136{
137 gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_VPE_BASE) +
138 GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe),
139 GIC_SH_MAP_TO_VPE_REG_BIT(vpe));
140}
141
142#ifdef CONFIG_CLKSRC_MIPS_GIC
143u64 notrace gic_read_count(void)
144{
145 unsigned int hi, hi2, lo;
146
147 if (mips_cm_is64)
148 return (u64)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER));
149
150 do {
151 hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
152 lo = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
153 hi2 = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
154 } while (hi2 != hi);
155
156 return (((u64) hi) << 32) + lo;
157}
158
159unsigned int gic_get_count_width(void)
160{
161 unsigned int bits, config;
162
163 config = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
164 bits = 32 + 4 * ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
165 GIC_SH_CONFIG_COUNTBITS_SHF);
166
167 return bits;
168}
169
170void notrace gic_write_compare(u64 cnt)
171{
172 if (mips_cm_is64) {
173 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt);
174 } else {
175 gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
176 (int)(cnt >> 32));
177 gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
178 (int)(cnt & 0xffffffff));
179 }
180}
181
182void notrace gic_write_cpu_compare(u64 cnt, int cpu)
183{
184 unsigned long flags;
185
186 local_irq_save(flags);
187
188 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), mips_cm_vp_id(cpu));
189
190 if (mips_cm_is64) {
191 gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt);
192 } else {
193 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
194 (int)(cnt >> 32));
195 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
196 (int)(cnt & 0xffffffff));
197 }
198
199 local_irq_restore(flags);
200}
201
202u64 gic_read_compare(void)
203{
204 unsigned int hi, lo;
205
206 if (mips_cm_is64)
207 return (u64)gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE));
208
209 hi = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
210 lo = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));
211
212 return (((u64) hi) << 32) + lo;
213}
214
215void gic_start_count(void)
216{ 59{
217 u32 gicconfig; 60 unsigned int i;
218
219 /* Start the counter */
220 gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
221 gicconfig &= ~(1 << GIC_SH_CONFIG_COUNTSTOP_SHF);
222 gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
223}
224
225void gic_stop_count(void)
226{
227 u32 gicconfig;
228
229 /* Stop the counter */
230 gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG));
231 gicconfig |= 1 << GIC_SH_CONFIG_COUNTSTOP_SHF;
232 gic_write(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
233}
234
235#endif
236
237unsigned gic_read_local_vp_id(void)
238{
239 unsigned long ident;
240 61
241 ident = gic_read(GIC_REG(VPE_LOCAL, GIC_VP_IDENT)); 62 /* Clear the interrupt's bit in all pcpu_masks */
242 return ident & GIC_VP_IDENT_VCNUM_MSK; 63 for_each_possible_cpu(i)
64 clear_bit(intr, per_cpu_ptr(pcpu_masks, i));
243} 65}
244 66
245static bool gic_local_irq_is_routable(int intr) 67static bool gic_local_irq_is_routable(int intr)
@@ -250,17 +72,17 @@ static bool gic_local_irq_is_routable(int intr)
250 if (cpu_has_veic) 72 if (cpu_has_veic)
251 return true; 73 return true;
252 74
253 vpe_ctl = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_CTL)); 75 vpe_ctl = read_gic_vl_ctl();
254 switch (intr) { 76 switch (intr) {
255 case GIC_LOCAL_INT_TIMER: 77 case GIC_LOCAL_INT_TIMER:
256 return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK; 78 return vpe_ctl & GIC_VX_CTL_TIMER_ROUTABLE;
257 case GIC_LOCAL_INT_PERFCTR: 79 case GIC_LOCAL_INT_PERFCTR:
258 return vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK; 80 return vpe_ctl & GIC_VX_CTL_PERFCNT_ROUTABLE;
259 case GIC_LOCAL_INT_FDC: 81 case GIC_LOCAL_INT_FDC:
260 return vpe_ctl & GIC_VPE_CTL_FDC_RTBL_MSK; 82 return vpe_ctl & GIC_VX_CTL_FDC_ROUTABLE;
261 case GIC_LOCAL_INT_SWINT0: 83 case GIC_LOCAL_INT_SWINT0:
262 case GIC_LOCAL_INT_SWINT1: 84 case GIC_LOCAL_INT_SWINT1:
263 return vpe_ctl & GIC_VPE_CTL_SWINT_RTBL_MSK; 85 return vpe_ctl & GIC_VX_CTL_SWINT_ROUTABLE;
264 default: 86 default:
265 return true; 87 return true;
266 } 88 }
@@ -272,15 +94,14 @@ static void gic_bind_eic_interrupt(int irq, int set)
272 irq -= GIC_PIN_TO_VEC_OFFSET; 94 irq -= GIC_PIN_TO_VEC_OFFSET;
273 95
274 /* Set irq to use shadow set */ 96 /* Set irq to use shadow set */
275 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_EIC_SHADOW_SET_BASE) + 97 write_gic_vl_eic_shadow_set(irq, set);
276 GIC_VPE_EIC_SS(irq), set);
277} 98}
278 99
279static void gic_send_ipi(struct irq_data *d, unsigned int cpu) 100static void gic_send_ipi(struct irq_data *d, unsigned int cpu)
280{ 101{
281 irq_hw_number_t hwirq = GIC_HWIRQ_TO_SHARED(irqd_to_hwirq(d)); 102 irq_hw_number_t hwirq = GIC_HWIRQ_TO_SHARED(irqd_to_hwirq(d));
282 103
283 gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(hwirq)); 104 write_gic_wedge(GIC_WEDGE_RW | hwirq);
284} 105}
285 106
286int gic_get_c0_compare_int(void) 107int gic_get_c0_compare_int(void)
@@ -316,47 +137,22 @@ int gic_get_c0_fdc_int(void)
316 GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC)); 137 GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC));
317} 138}
318 139
319int gic_get_usm_range(struct resource *gic_usm_res)
320{
321 if (!gic_present)
322 return -1;
323
324 gic_usm_res->start = __gic_base_addr + USM_VISIBLE_SECTION_OFS;
325 gic_usm_res->end = gic_usm_res->start + (USM_VISIBLE_SECTION_SIZE - 1);
326
327 return 0;
328}
329
330static void gic_handle_shared_int(bool chained) 140static void gic_handle_shared_int(bool chained)
331{ 141{
332 unsigned int i, intr, virq, gic_reg_step = mips_cm_is64 ? 8 : 4; 142 unsigned int intr, virq;
333 unsigned long *pcpu_mask; 143 unsigned long *pcpu_mask;
334 unsigned long pending_reg, intrmask_reg;
335 DECLARE_BITMAP(pending, GIC_MAX_INTRS); 144 DECLARE_BITMAP(pending, GIC_MAX_INTRS);
336 DECLARE_BITMAP(intrmask, GIC_MAX_INTRS);
337 145
338 /* Get per-cpu bitmaps */ 146 /* Get per-cpu bitmaps */
339 pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; 147 pcpu_mask = this_cpu_ptr(pcpu_masks);
340
341 pending_reg = GIC_REG(SHARED, GIC_SH_PEND);
342 intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK);
343
344 for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) {
345 pending[i] = gic_read(pending_reg);
346 intrmask[i] = gic_read(intrmask_reg);
347 pending_reg += gic_reg_step;
348 intrmask_reg += gic_reg_step;
349
350 if (!IS_ENABLED(CONFIG_64BIT) || mips_cm_is64)
351 continue;
352 148
353 pending[i] |= (u64)gic_read(pending_reg) << 32; 149 if (mips_cm_is64)
354 intrmask[i] |= (u64)gic_read(intrmask_reg) << 32; 150 __ioread64_copy(pending, addr_gic_pend(),
355 pending_reg += gic_reg_step; 151 DIV_ROUND_UP(gic_shared_intrs, 64));
356 intrmask_reg += gic_reg_step; 152 else
357 } 153 __ioread32_copy(pending, addr_gic_pend(),
154 DIV_ROUND_UP(gic_shared_intrs, 32));
358 155
359 bitmap_and(pending, pending, intrmask, gic_shared_intrs);
360 bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs); 156 bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
361 157
362 for_each_set_bit(intr, pending, gic_shared_intrs) { 158 for_each_set_bit(intr, pending, gic_shared_intrs) {
@@ -371,19 +167,30 @@ static void gic_handle_shared_int(bool chained)
371 167
372static void gic_mask_irq(struct irq_data *d) 168static void gic_mask_irq(struct irq_data *d)
373{ 169{
374 gic_reset_mask(GIC_HWIRQ_TO_SHARED(d->hwirq)); 170 unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
171
172 write_gic_rmask(BIT(intr));
173 gic_clear_pcpu_masks(intr);
375} 174}
376 175
377static void gic_unmask_irq(struct irq_data *d) 176static void gic_unmask_irq(struct irq_data *d)
378{ 177{
379 gic_set_mask(GIC_HWIRQ_TO_SHARED(d->hwirq)); 178 struct cpumask *affinity = irq_data_get_affinity_mask(d);
179 unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq);
180 unsigned int cpu;
181
182 write_gic_smask(BIT(intr));
183
184 gic_clear_pcpu_masks(intr);
185 cpu = cpumask_first_and(affinity, cpu_online_mask);
186 set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
380} 187}
381 188
382static void gic_ack_irq(struct irq_data *d) 189static void gic_ack_irq(struct irq_data *d)
383{ 190{
384 unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); 191 unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
385 192
386 gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_CLR(irq)); 193 write_gic_wedge(irq);
387} 194}
388 195
389static int gic_set_type(struct irq_data *d, unsigned int type) 196static int gic_set_type(struct irq_data *d, unsigned int type)
@@ -395,34 +202,34 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
395 spin_lock_irqsave(&gic_lock, flags); 202 spin_lock_irqsave(&gic_lock, flags);
396 switch (type & IRQ_TYPE_SENSE_MASK) { 203 switch (type & IRQ_TYPE_SENSE_MASK) {
397 case IRQ_TYPE_EDGE_FALLING: 204 case IRQ_TYPE_EDGE_FALLING:
398 gic_set_polarity(irq, GIC_POL_NEG); 205 change_gic_pol(irq, GIC_POL_FALLING_EDGE);
399 gic_set_trigger(irq, GIC_TRIG_EDGE); 206 change_gic_trig(irq, GIC_TRIG_EDGE);
400 gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); 207 change_gic_dual(irq, GIC_DUAL_SINGLE);
401 is_edge = true; 208 is_edge = true;
402 break; 209 break;
403 case IRQ_TYPE_EDGE_RISING: 210 case IRQ_TYPE_EDGE_RISING:
404 gic_set_polarity(irq, GIC_POL_POS); 211 change_gic_pol(irq, GIC_POL_RISING_EDGE);
405 gic_set_trigger(irq, GIC_TRIG_EDGE); 212 change_gic_trig(irq, GIC_TRIG_EDGE);
406 gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); 213 change_gic_dual(irq, GIC_DUAL_SINGLE);
407 is_edge = true; 214 is_edge = true;
408 break; 215 break;
409 case IRQ_TYPE_EDGE_BOTH: 216 case IRQ_TYPE_EDGE_BOTH:
410 /* polarity is irrelevant in this case */ 217 /* polarity is irrelevant in this case */
411 gic_set_trigger(irq, GIC_TRIG_EDGE); 218 change_gic_trig(irq, GIC_TRIG_EDGE);
412 gic_set_dual_edge(irq, GIC_TRIG_DUAL_ENABLE); 219 change_gic_dual(irq, GIC_DUAL_DUAL);
413 is_edge = true; 220 is_edge = true;
414 break; 221 break;
415 case IRQ_TYPE_LEVEL_LOW: 222 case IRQ_TYPE_LEVEL_LOW:
416 gic_set_polarity(irq, GIC_POL_NEG); 223 change_gic_pol(irq, GIC_POL_ACTIVE_LOW);
417 gic_set_trigger(irq, GIC_TRIG_LEVEL); 224 change_gic_trig(irq, GIC_TRIG_LEVEL);
418 gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); 225 change_gic_dual(irq, GIC_DUAL_SINGLE);
419 is_edge = false; 226 is_edge = false;
420 break; 227 break;
421 case IRQ_TYPE_LEVEL_HIGH: 228 case IRQ_TYPE_LEVEL_HIGH:
422 default: 229 default:
423 gic_set_polarity(irq, GIC_POL_POS); 230 change_gic_pol(irq, GIC_POL_ACTIVE_HIGH);
424 gic_set_trigger(irq, GIC_TRIG_LEVEL); 231 change_gic_trig(irq, GIC_TRIG_LEVEL);
425 gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); 232 change_gic_dual(irq, GIC_DUAL_SINGLE);
426 is_edge = false; 233 is_edge = false;
427 break; 234 break;
428 } 235 }
@@ -443,32 +250,28 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
443 bool force) 250 bool force)
444{ 251{
445 unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); 252 unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
446 cpumask_t tmp = CPU_MASK_NONE; 253 unsigned long flags;
447 unsigned long flags; 254 unsigned int cpu;
448 int i, cpu;
449 255
450 cpumask_and(&tmp, cpumask, cpu_online_mask); 256 cpu = cpumask_first_and(cpumask, cpu_online_mask);
451 if (cpumask_empty(&tmp)) 257 if (cpu >= NR_CPUS)
452 return -EINVAL; 258 return -EINVAL;
453 259
454 cpu = cpumask_first(&tmp);
455
456 /* Assumption : cpumask refers to a single CPU */ 260 /* Assumption : cpumask refers to a single CPU */
457 spin_lock_irqsave(&gic_lock, flags); 261 spin_lock_irqsave(&gic_lock, flags);
458 262
459 /* Re-route this IRQ */ 263 /* Re-route this IRQ */
460 gic_map_to_vpe(irq, mips_cm_vp_id(cpu)); 264 write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
461 265
462 /* Update the pcpu_masks */ 266 /* Update the pcpu_masks */
463 for (i = 0; i < min(gic_vpes, NR_CPUS); i++) 267 gic_clear_pcpu_masks(irq);
464 clear_bit(irq, pcpu_masks[i].pcpu_mask); 268 if (read_gic_mask(irq))
465 set_bit(irq, pcpu_masks[cpu].pcpu_mask); 269 set_bit(irq, per_cpu_ptr(pcpu_masks, cpu));
466 270
467 cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
468 irq_data_update_effective_affinity(d, cpumask_of(cpu)); 271 irq_data_update_effective_affinity(d, cpumask_of(cpu));
469 spin_unlock_irqrestore(&gic_lock, flags); 272 spin_unlock_irqrestore(&gic_lock, flags);
470 273
471 return IRQ_SET_MASK_OK_NOCOPY; 274 return IRQ_SET_MASK_OK;
472} 275}
473#endif 276#endif
474 277
@@ -499,8 +302,8 @@ static void gic_handle_local_int(bool chained)
499 unsigned long pending, masked; 302 unsigned long pending, masked;
500 unsigned int intr, virq; 303 unsigned int intr, virq;
501 304
502 pending = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_PEND)); 305 pending = read_gic_vl_pend();
503 masked = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_MASK)); 306 masked = read_gic_vl_mask();
504 307
505 bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS); 308 bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
506 309
@@ -518,14 +321,14 @@ static void gic_mask_local_irq(struct irq_data *d)
518{ 321{
519 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); 322 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
520 323
521 gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr); 324 write_gic_vl_rmask(BIT(intr));
522} 325}
523 326
524static void gic_unmask_local_irq(struct irq_data *d) 327static void gic_unmask_local_irq(struct irq_data *d)
525{ 328{
526 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); 329 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
527 330
528 gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr); 331 write_gic_vl_smask(BIT(intr));
529} 332}
530 333
531static struct irq_chip gic_local_irq_controller = { 334static struct irq_chip gic_local_irq_controller = {
@@ -542,9 +345,8 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
542 345
543 spin_lock_irqsave(&gic_lock, flags); 346 spin_lock_irqsave(&gic_lock, flags);
544 for (i = 0; i < gic_vpes; i++) { 347 for (i = 0; i < gic_vpes; i++) {
545 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 348 write_gic_vl_other(mips_cm_vp_id(i));
546 mips_cm_vp_id(i)); 349 write_gic_vo_rmask(BIT(intr));
547 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr);
548 } 350 }
549 spin_unlock_irqrestore(&gic_lock, flags); 351 spin_unlock_irqrestore(&gic_lock, flags);
550} 352}
@@ -557,9 +359,8 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
557 359
558 spin_lock_irqsave(&gic_lock, flags); 360 spin_lock_irqsave(&gic_lock, flags);
559 for (i = 0; i < gic_vpes; i++) { 361 for (i = 0; i < gic_vpes; i++) {
560 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 362 write_gic_vl_other(mips_cm_vp_id(i));
561 mips_cm_vp_id(i)); 363 write_gic_vo_smask(BIT(intr));
562 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr);
563 } 364 }
564 spin_unlock_irqrestore(&gic_lock, flags); 365 spin_unlock_irqrestore(&gic_lock, flags);
565} 366}
@@ -582,103 +383,50 @@ static void gic_irq_dispatch(struct irq_desc *desc)
582 gic_handle_shared_int(true); 383 gic_handle_shared_int(true);
583} 384}
584 385
585static void __init gic_basic_init(void)
586{
587 unsigned int i;
588
589 board_bind_eic_interrupt = &gic_bind_eic_interrupt;
590
591 /* Setup defaults */
592 for (i = 0; i < gic_shared_intrs; i++) {
593 gic_set_polarity(i, GIC_POL_POS);
594 gic_set_trigger(i, GIC_TRIG_LEVEL);
595 gic_reset_mask(i);
596 }
597
598 for (i = 0; i < gic_vpes; i++) {
599 unsigned int j;
600
601 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
602 mips_cm_vp_id(i));
603 for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
604 if (!gic_local_irq_is_routable(j))
605 continue;
606 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j);
607 }
608 }
609}
610
611static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, 386static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
612 irq_hw_number_t hw) 387 irq_hw_number_t hw)
613{ 388{
614 int intr = GIC_HWIRQ_TO_LOCAL(hw); 389 int intr = GIC_HWIRQ_TO_LOCAL(hw);
615 int ret = 0;
616 int i; 390 int i;
617 unsigned long flags; 391 unsigned long flags;
392 u32 val;
618 393
619 if (!gic_local_irq_is_routable(intr)) 394 if (!gic_local_irq_is_routable(intr))
620 return -EPERM; 395 return -EPERM;
621 396
397 if (intr > GIC_LOCAL_INT_FDC) {
398 pr_err("Invalid local IRQ %d\n", intr);
399 return -EINVAL;
400 }
401
402 if (intr == GIC_LOCAL_INT_TIMER) {
403 /* CONFIG_MIPS_CMP workaround (see __gic_init) */
404 val = GIC_MAP_PIN_MAP_TO_PIN | timer_cpu_pin;
405 } else {
406 val = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin;
407 }
408
622 spin_lock_irqsave(&gic_lock, flags); 409 spin_lock_irqsave(&gic_lock, flags);
623 for (i = 0; i < gic_vpes; i++) { 410 for (i = 0; i < gic_vpes; i++) {
624 u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; 411 write_gic_vl_other(mips_cm_vp_id(i));
625 412 write_gic_vo_map(intr, val);
626 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR),
627 mips_cm_vp_id(i));
628
629 switch (intr) {
630 case GIC_LOCAL_INT_WD:
631 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val);
632 break;
633 case GIC_LOCAL_INT_COMPARE:
634 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP),
635 val);
636 break;
637 case GIC_LOCAL_INT_TIMER:
638 /* CONFIG_MIPS_CMP workaround (see __gic_init) */
639 val = GIC_MAP_TO_PIN_MSK | timer_cpu_pin;
640 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
641 val);
642 break;
643 case GIC_LOCAL_INT_PERFCTR:
644 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
645 val);
646 break;
647 case GIC_LOCAL_INT_SWINT0:
648 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP),
649 val);
650 break;
651 case GIC_LOCAL_INT_SWINT1:
652 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP),
653 val);
654 break;
655 case GIC_LOCAL_INT_FDC:
656 gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val);
657 break;
658 default:
659 pr_err("Invalid local IRQ %d\n", intr);
660 ret = -EINVAL;
661 break;
662 }
663 } 413 }
664 spin_unlock_irqrestore(&gic_lock, flags); 414 spin_unlock_irqrestore(&gic_lock, flags);
665 415
666 return ret; 416 return 0;
667} 417}
668 418
669static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, 419static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
670 irq_hw_number_t hw, unsigned int vpe) 420 irq_hw_number_t hw, unsigned int cpu)
671{ 421{
672 int intr = GIC_HWIRQ_TO_SHARED(hw); 422 int intr = GIC_HWIRQ_TO_SHARED(hw);
673 unsigned long flags; 423 unsigned long flags;
674 int i;
675 424
676 spin_lock_irqsave(&gic_lock, flags); 425 spin_lock_irqsave(&gic_lock, flags);
677 gic_map_to_pin(intr, gic_cpu_pin); 426 write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
678 gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); 427 write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
679 for (i = 0; i < min(gic_vpes, NR_CPUS); i++) 428 gic_clear_pcpu_masks(intr);
680 clear_bit(intr, pcpu_masks[i].pcpu_mask); 429 set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
681 set_bit(intr, pcpu_masks[vpe].pcpu_mask);
682 spin_unlock_irqrestore(&gic_lock, flags); 430 spin_unlock_irqrestore(&gic_lock, flags);
683 431
684 return 0; 432 return 0;
@@ -885,34 +633,69 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
885 .match = gic_ipi_domain_match, 633 .match = gic_ipi_domain_match,
886}; 634};
887 635
888static void __init __gic_init(unsigned long gic_base_addr, 636
889 unsigned long gic_addrspace_size, 637static int __init gic_of_init(struct device_node *node,
890 unsigned int cpu_vec, unsigned int irqbase, 638 struct device_node *parent)
891 struct device_node *node)
892{ 639{
893 unsigned int gicconfig, cpu; 640 unsigned int cpu_vec, i, j, gicconfig, cpu, v[2];
894 unsigned int v[2]; 641 unsigned long reserved;
642 phys_addr_t gic_base;
643 struct resource res;
644 size_t gic_len;
645
646 /* Find the first available CPU vector. */
647 i = 0;
648 reserved = (C_SW0 | C_SW1) >> __fls(C_SW0);
649 while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors",
650 i++, &cpu_vec))
651 reserved |= BIT(cpu_vec);
652
653 cpu_vec = find_first_zero_bit(&reserved, hweight_long(ST0_IM));
654 if (cpu_vec == hweight_long(ST0_IM)) {
655 pr_err("No CPU vectors available for GIC\n");
656 return -ENODEV;
657 }
658
659 if (of_address_to_resource(node, 0, &res)) {
660 /*
661 * Probe the CM for the GIC base address if not specified
662 * in the device-tree.
663 */
664 if (mips_cm_present()) {
665 gic_base = read_gcr_gic_base() &
666 ~CM_GCR_GIC_BASE_GICEN;
667 gic_len = 0x20000;
668 } else {
669 pr_err("Failed to get GIC memory range\n");
670 return -ENODEV;
671 }
672 } else {
673 gic_base = res.start;
674 gic_len = resource_size(&res);
675 }
895 676
896 __gic_base_addr = gic_base_addr; 677 if (mips_cm_present()) {
678 write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
679 /* Ensure GIC region is enabled before trying to access it */
680 __sync();
681 }
897 682
898 gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size); 683 mips_gic_base = ioremap_nocache(gic_base, gic_len);
899 684
900 gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG)); 685 gicconfig = read_gic_config();
901 gic_shared_intrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> 686 gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
902 GIC_SH_CONFIG_NUMINTRS_SHF; 687 gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS);
903 gic_shared_intrs = ((gic_shared_intrs + 1) * 8); 688 gic_shared_intrs = (gic_shared_intrs + 1) * 8;
904 689
905 gic_vpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> 690 gic_vpes = gicconfig & GIC_CONFIG_PVPS;
906 GIC_SH_CONFIG_NUMVPES_SHF; 691 gic_vpes >>= __fls(GIC_CONFIG_PVPS);
907 gic_vpes = gic_vpes + 1; 692 gic_vpes = gic_vpes + 1;
908 693
909 if (cpu_has_veic) { 694 if (cpu_has_veic) {
910 /* Set EIC mode for all VPEs */ 695 /* Set EIC mode for all VPEs */
911 for_each_present_cpu(cpu) { 696 for_each_present_cpu(cpu) {
912 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 697 write_gic_vl_other(mips_cm_vp_id(cpu));
913 mips_cm_vp_id(cpu)); 698 write_gic_vo_ctl(GIC_VX_CTL_EIC);
914 gic_write(GIC_REG(VPE_OTHER, GIC_VPE_CTL),
915 GIC_VPE_CTL_EIC_MODE_MSK);
916 } 699 }
917 700
918 /* Always use vector 1 in EIC mode */ 701 /* Always use vector 1 in EIC mode */
@@ -937,9 +720,7 @@ static void __init __gic_init(unsigned long gic_base_addr,
937 */ 720 */
938 if (IS_ENABLED(CONFIG_MIPS_CMP) && 721 if (IS_ENABLED(CONFIG_MIPS_CMP) &&
939 gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) { 722 gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) {
940 timer_cpu_pin = gic_read32(GIC_REG(VPE_LOCAL, 723 timer_cpu_pin = read_gic_vl_timer_map() & GIC_MAP_PIN_MAP;
941 GIC_VPE_TIMER_MAP)) &
942 GIC_MAP_MSK;
943 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 724 irq_set_chained_handler(MIPS_CPU_IRQ_BASE +
944 GIC_CPU_PIN_OFFSET + 725 GIC_CPU_PIN_OFFSET +
945 timer_cpu_pin, 726 timer_cpu_pin,
@@ -950,17 +731,21 @@ static void __init __gic_init(unsigned long gic_base_addr,
950 } 731 }
951 732
952 gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS + 733 gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS +
953 gic_shared_intrs, irqbase, 734 gic_shared_intrs, 0,
954 &gic_irq_domain_ops, NULL); 735 &gic_irq_domain_ops, NULL);
955 if (!gic_irq_domain) 736 if (!gic_irq_domain) {
956 panic("Failed to add GIC IRQ domain"); 737 pr_err("Failed to add GIC IRQ domain");
738 return -ENXIO;
739 }
957 740
958 gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain, 741 gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
959 IRQ_DOMAIN_FLAG_IPI_PER_CPU, 742 IRQ_DOMAIN_FLAG_IPI_PER_CPU,
960 GIC_NUM_LOCAL_INTRS + gic_shared_intrs, 743 GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
961 node, &gic_ipi_domain_ops, NULL); 744 node, &gic_ipi_domain_ops, NULL);
962 if (!gic_ipi_domain) 745 if (!gic_ipi_domain) {
963 panic("Failed to add GIC IPI domain"); 746 pr_err("Failed to add GIC IPI domain");
747 return -ENXIO;
748 }
964 749
965 irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI); 750 irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI);
966 751
@@ -975,64 +760,25 @@ static void __init __gic_init(unsigned long gic_base_addr,
975 } 760 }
976 761
977 bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS); 762 bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
978 gic_basic_init();
979}
980
981void __init gic_init(unsigned long gic_base_addr,
982 unsigned long gic_addrspace_size,
983 unsigned int cpu_vec, unsigned int irqbase)
984{
985 __gic_init(gic_base_addr, gic_addrspace_size, cpu_vec, irqbase, NULL);
986}
987 763
988static int __init gic_of_init(struct device_node *node, 764 board_bind_eic_interrupt = &gic_bind_eic_interrupt;
989 struct device_node *parent)
990{
991 struct resource res;
992 unsigned int cpu_vec, i = 0, reserved = 0;
993 phys_addr_t gic_base;
994 size_t gic_len;
995 765
996 /* Find the first available CPU vector. */ 766 /* Setup defaults */
997 while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", 767 for (i = 0; i < gic_shared_intrs; i++) {
998 i++, &cpu_vec)) 768 change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
999 reserved |= BIT(cpu_vec); 769 change_gic_trig(i, GIC_TRIG_LEVEL);
1000 for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) { 770 write_gic_rmask(BIT(i));
1001 if (!(reserved & BIT(cpu_vec)))
1002 break;
1003 }
1004 if (cpu_vec == 8) {
1005 pr_err("No CPU vectors available for GIC\n");
1006 return -ENODEV;
1007 } 771 }
1008 772
1009 if (of_address_to_resource(node, 0, &res)) { 773 for (i = 0; i < gic_vpes; i++) {
1010 /* 774 write_gic_vl_other(mips_cm_vp_id(i));
1011 * Probe the CM for the GIC base address if not specified 775 for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
1012 * in the device-tree. 776 if (!gic_local_irq_is_routable(j))
1013 */ 777 continue;
1014 if (mips_cm_present()) { 778 write_gic_vo_rmask(BIT(j));
1015 gic_base = read_gcr_gic_base() &
1016 ~CM_GCR_GIC_BASE_GICEN_MSK;
1017 gic_len = 0x20000;
1018 } else {
1019 pr_err("Failed to get GIC memory range\n");
1020 return -ENODEV;
1021 } 779 }
1022 } else {
1023 gic_base = res.start;
1024 gic_len = resource_size(&res);
1025 } 780 }
1026 781
1027 if (mips_cm_present()) {
1028 write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK);
1029 /* Ensure GIC region is enabled before trying to access it */
1030 __sync();
1031 }
1032 gic_present = true;
1033
1034 __gic_init(gic_base, gic_len, cpu_vec, 0, node);
1035
1036 return 0; 782 return 0;
1037} 783}
1038IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init); 784IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init);
diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c
index 3e33ab66eb24..77b1d8013295 100644
--- a/drivers/mtd/maps/lantiq-flash.c
+++ b/drivers/mtd/maps/lantiq-flash.c
@@ -114,12 +114,6 @@ ltq_mtd_probe(struct platform_device *pdev)
114 struct cfi_private *cfi; 114 struct cfi_private *cfi;
115 int err; 115 int err;
116 116
117 if (of_machine_is_compatible("lantiq,falcon") &&
118 (ltq_boot_select() != BS_FLASH)) {
119 dev_err(&pdev->dev, "invalid bootstrap options\n");
120 return -ENODEV;
121 }
122
123 ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL); 117 ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL);
124 if (!ltq_mtd) 118 if (!ltq_mtd)
125 return -ENOMEM; 119 return -ENOMEM;
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
index 944674ee3464..19e17829f515 100644
--- a/drivers/pcmcia/db1xxx_ss.c
+++ b/drivers/pcmcia/db1xxx_ss.c
@@ -131,22 +131,27 @@ static irqreturn_t db1000_pcmcia_stschgirq(int irq, void *data)
131 return IRQ_HANDLED; 131 return IRQ_HANDLED;
132} 132}
133 133
134/* Db/Pb1200 have separate per-socket insertion and ejection
135 * interrupts which stay asserted as long as the card is
136 * inserted/missing. The one which caused us to be called
137 * needs to be disabled and the other one enabled.
138 */
134static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data) 139static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data)
135{ 140{
141 disable_irq_nosync(irq);
142 return IRQ_WAKE_THREAD;
143}
144
145static irqreturn_t db1200_pcmcia_cdirq_fn(int irq, void *data)
146{
136 struct db1x_pcmcia_sock *sock = data; 147 struct db1x_pcmcia_sock *sock = data;
137 148
138 /* Db/Pb1200 have separate per-socket insertion and ejection 149 /* Wait a bit for the signals to stop bouncing. */
139 * interrupts which stay asserted as long as the card is 150 msleep(100);
140 * inserted/missing. The one which caused us to be called 151 if (irq == sock->insert_irq)
141 * needs to be disabled and the other one enabled.
142 */
143 if (irq == sock->insert_irq) {
144 disable_irq_nosync(sock->insert_irq);
145 enable_irq(sock->eject_irq); 152 enable_irq(sock->eject_irq);
146 } else { 153 else
147 disable_irq_nosync(sock->eject_irq);
148 enable_irq(sock->insert_irq); 154 enable_irq(sock->insert_irq);
149 }
150 155
151 pcmcia_parse_events(&sock->socket, SS_DETECT); 156 pcmcia_parse_events(&sock->socket, SS_DETECT);
152 157
@@ -172,13 +177,13 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
172 */ 177 */
173 if ((sock->board_type == BOARD_TYPE_DB1200) || 178 if ((sock->board_type == BOARD_TYPE_DB1200) ||
174 (sock->board_type == BOARD_TYPE_DB1300)) { 179 (sock->board_type == BOARD_TYPE_DB1300)) {
175 ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, 180 ret = request_threaded_irq(sock->insert_irq, db1200_pcmcia_cdirq,
176 0, "pcmcia_insert", sock); 181 db1200_pcmcia_cdirq_fn, 0, "pcmcia_insert", sock);
177 if (ret) 182 if (ret)
178 goto out1; 183 goto out1;
179 184
180 ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, 185 ret = request_threaded_irq(sock->eject_irq, db1200_pcmcia_cdirq,
181 0, "pcmcia_eject", sock); 186 db1200_pcmcia_cdirq_fn, 0, "pcmcia_eject", sock);
182 if (ret) { 187 if (ret) {
183 free_irq(sock->insert_irq, sock); 188 free_irq(sock->insert_irq, sock);
184 goto out1; 189 goto out1;
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 441912c10b82..5c8d452e35e2 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -44,6 +44,7 @@ source "drivers/phy/allwinner/Kconfig"
44source "drivers/phy/amlogic/Kconfig" 44source "drivers/phy/amlogic/Kconfig"
45source "drivers/phy/broadcom/Kconfig" 45source "drivers/phy/broadcom/Kconfig"
46source "drivers/phy/hisilicon/Kconfig" 46source "drivers/phy/hisilicon/Kconfig"
47source "drivers/phy/lantiq/Kconfig"
47source "drivers/phy/marvell/Kconfig" 48source "drivers/phy/marvell/Kconfig"
48source "drivers/phy/mediatek/Kconfig" 49source "drivers/phy/mediatek/Kconfig"
49source "drivers/phy/motorola/Kconfig" 50source "drivers/phy/motorola/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 06f3c500030d..3a52dcb09566 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -6,9 +6,9 @@ obj-$(CONFIG_GENERIC_PHY) += phy-core.o
6obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o 6obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
7obj-$(CONFIG_PHY_XGENE) += phy-xgene.o 7obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
8obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o 8obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
9
10obj-$(CONFIG_ARCH_SUNXI) += allwinner/ 9obj-$(CONFIG_ARCH_SUNXI) += allwinner/
11obj-$(CONFIG_ARCH_MESON) += amlogic/ 10obj-$(CONFIG_ARCH_MESON) += amlogic/
11obj-$(CONFIG_LANTIQ) += lantiq/
12obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ 12obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
13obj-$(CONFIG_ARCH_RENESAS) += renesas/ 13obj-$(CONFIG_ARCH_RENESAS) += renesas/
14obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ 14obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
diff --git a/drivers/phy/lantiq/Kconfig b/drivers/phy/lantiq/Kconfig
new file mode 100644
index 000000000000..326d88a6417d
--- /dev/null
+++ b/drivers/phy/lantiq/Kconfig
@@ -0,0 +1,9 @@
1#
2# Phy drivers for Lantiq / Intel platforms
3#
4config PHY_LANTIQ_RCU_USB2
5 tristate "Lantiq XWAY SoC RCU based USB PHY"
6 depends on OF && (SOC_TYPE_XWAY || COMPILE_TEST)
7 select GENERIC_PHY
8 help
9 Support for the USB PHY(s) on the Lantiq / Intel XWAY family SoCs.
diff --git a/drivers/phy/lantiq/Makefile b/drivers/phy/lantiq/Makefile
new file mode 100644
index 000000000000..f73eb56a5416
--- /dev/null
+++ b/drivers/phy/lantiq/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_PHY_LANTIQ_RCU_USB2) += phy-lantiq-rcu-usb2.o
diff --git a/drivers/phy/lantiq/phy-lantiq-rcu-usb2.c b/drivers/phy/lantiq/phy-lantiq-rcu-usb2.c
new file mode 100644
index 000000000000..986224fca9e9
--- /dev/null
+++ b/drivers/phy/lantiq/phy-lantiq-rcu-usb2.c
@@ -0,0 +1,254 @@
1/*
2 * Lantiq XWAY SoC RCU module based USB 1.1/2.0 PHY driver
3 *
4 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
5 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/mfd/syscon.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/of_device.h>
19#include <linux/phy/phy.h>
20#include <linux/platform_device.h>
21#include <linux/property.h>
22#include <linux/regmap.h>
23#include <linux/reset.h>
24
25/* Transmitter HS Pre-Emphasis Enable */
26#define RCU_CFG1_TX_PEE BIT(0)
27/* Disconnect Threshold */
28#define RCU_CFG1_DIS_THR_MASK 0x00038000
29#define RCU_CFG1_DIS_THR_SHIFT 15
30
31struct ltq_rcu_usb2_bits {
32 u8 hostmode;
33 u8 slave_endianness;
34 u8 host_endianness;
35 bool have_ana_cfg;
36};
37
38struct ltq_rcu_usb2_priv {
39 struct regmap *regmap;
40 unsigned int phy_reg_offset;
41 unsigned int ana_cfg1_reg_offset;
42 const struct ltq_rcu_usb2_bits *reg_bits;
43 struct device *dev;
44 struct phy *phy;
45 struct clk *phy_gate_clk;
46 struct reset_control *ctrl_reset;
47 struct reset_control *phy_reset;
48};
49
50static const struct ltq_rcu_usb2_bits xway_rcu_usb2_reg_bits = {
51 .hostmode = 11,
52 .slave_endianness = 9,
53 .host_endianness = 10,
54 .have_ana_cfg = false,
55};
56
57static const struct ltq_rcu_usb2_bits xrx100_rcu_usb2_reg_bits = {
58 .hostmode = 11,
59 .slave_endianness = 17,
60 .host_endianness = 10,
61 .have_ana_cfg = false,
62};
63
64static const struct ltq_rcu_usb2_bits xrx200_rcu_usb2_reg_bits = {
65 .hostmode = 11,
66 .slave_endianness = 9,
67 .host_endianness = 10,
68 .have_ana_cfg = true,
69};
70
71static const struct of_device_id ltq_rcu_usb2_phy_of_match[] = {
72 {
73 .compatible = "lantiq,ase-usb2-phy",
74 .data = &xway_rcu_usb2_reg_bits,
75 },
76 {
77 .compatible = "lantiq,danube-usb2-phy",
78 .data = &xway_rcu_usb2_reg_bits,
79 },
80 {
81 .compatible = "lantiq,xrx100-usb2-phy",
82 .data = &xrx100_rcu_usb2_reg_bits,
83 },
84 {
85 .compatible = "lantiq,xrx200-usb2-phy",
86 .data = &xrx200_rcu_usb2_reg_bits,
87 },
88 {
89 .compatible = "lantiq,xrx300-usb2-phy",
90 .data = &xrx200_rcu_usb2_reg_bits,
91 },
92 { },
93};
94MODULE_DEVICE_TABLE(of, ltq_rcu_usb2_phy_of_match);
95
96static int ltq_rcu_usb2_phy_init(struct phy *phy)
97{
98 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
99
100 if (priv->reg_bits->have_ana_cfg) {
101 regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset,
102 RCU_CFG1_TX_PEE, RCU_CFG1_TX_PEE);
103 regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset,
104 RCU_CFG1_DIS_THR_MASK, 7 << RCU_CFG1_DIS_THR_SHIFT);
105 }
106
107 /* Configure core to host mode */
108 regmap_update_bits(priv->regmap, priv->phy_reg_offset,
109 BIT(priv->reg_bits->hostmode), 0);
110
111 /* Select DMA endianness (Host-endian: big-endian) */
112 regmap_update_bits(priv->regmap, priv->phy_reg_offset,
113 BIT(priv->reg_bits->slave_endianness), 0);
114 regmap_update_bits(priv->regmap, priv->phy_reg_offset,
115 BIT(priv->reg_bits->host_endianness),
116 BIT(priv->reg_bits->host_endianness));
117
118 return 0;
119}
120
121static int ltq_rcu_usb2_phy_power_on(struct phy *phy)
122{
123 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
124 struct device *dev = priv->dev;
125 int ret;
126
127 reset_control_deassert(priv->phy_reset);
128
129 ret = clk_prepare_enable(priv->phy_gate_clk);
130 if (ret)
131 dev_err(dev, "failed to enable PHY gate\n");
132
133 return ret;
134}
135
136static int ltq_rcu_usb2_phy_power_off(struct phy *phy)
137{
138 struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
139
140 reset_control_assert(priv->phy_reset);
141
142 clk_disable_unprepare(priv->phy_gate_clk);
143
144 return 0;
145}
146
147static struct phy_ops ltq_rcu_usb2_phy_ops = {
148 .init = ltq_rcu_usb2_phy_init,
149 .power_on = ltq_rcu_usb2_phy_power_on,
150 .power_off = ltq_rcu_usb2_phy_power_off,
151 .owner = THIS_MODULE,
152};
153
154static int ltq_rcu_usb2_of_parse(struct ltq_rcu_usb2_priv *priv,
155 struct platform_device *pdev)
156{
157 struct device *dev = priv->dev;
158 const __be32 *offset;
159 int ret;
160
161 priv->reg_bits = of_device_get_match_data(dev);
162
163 priv->regmap = syscon_node_to_regmap(dev->of_node->parent);
164 if (IS_ERR(priv->regmap)) {
165 dev_err(dev, "Failed to lookup RCU regmap\n");
166 return PTR_ERR(priv->regmap);
167 }
168
169 offset = of_get_address(dev->of_node, 0, NULL, NULL);
170 if (!offset) {
171 dev_err(dev, "Failed to get RCU PHY reg offset\n");
172 return -ENOENT;
173 }
174 priv->phy_reg_offset = __be32_to_cpu(*offset);
175
176 if (priv->reg_bits->have_ana_cfg) {
177 offset = of_get_address(dev->of_node, 1, NULL, NULL);
178 if (!offset) {
179 dev_err(dev, "Failed to get RCU ANA CFG1 reg offset\n");
180 return -ENOENT;
181 }
182 priv->ana_cfg1_reg_offset = __be32_to_cpu(*offset);
183 }
184
185 priv->phy_gate_clk = devm_clk_get(dev, "phy");
186 if (IS_ERR(priv->phy_gate_clk)) {
187 dev_err(dev, "Unable to get USB phy gate clk\n");
188 return PTR_ERR(priv->phy_gate_clk);
189 }
190
191 priv->ctrl_reset = devm_reset_control_get_shared(dev, "ctrl");
192 if (IS_ERR(priv->ctrl_reset)) {
193 if (PTR_ERR(priv->ctrl_reset) != -EPROBE_DEFER)
194 dev_err(dev, "failed to get 'ctrl' reset\n");
195 return PTR_ERR(priv->ctrl_reset);
196 }
197
198 priv->phy_reset = devm_reset_control_get_optional(dev, "phy");
199 if (IS_ERR(priv->phy_reset))
200 return PTR_ERR(priv->phy_reset);
201
202 return 0;
203}
204
205static int ltq_rcu_usb2_phy_probe(struct platform_device *pdev)
206{
207 struct device *dev = &pdev->dev;
208 struct ltq_rcu_usb2_priv *priv;
209 struct phy_provider *provider;
210 int ret;
211
212 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
213 if (!priv)
214 return -ENOMEM;
215
216 priv->dev = dev;
217
218 ret = ltq_rcu_usb2_of_parse(priv, pdev);
219 if (ret)
220 return ret;
221
222 /* Reset USB core through reset controller */
223 reset_control_deassert(priv->ctrl_reset);
224
225 reset_control_assert(priv->phy_reset);
226
227 priv->phy = devm_phy_create(dev, dev->of_node, &ltq_rcu_usb2_phy_ops);
228 if (IS_ERR(priv->phy)) {
229 dev_err(dev, "failed to create PHY\n");
230 return PTR_ERR(priv->phy);
231 }
232
233 phy_set_drvdata(priv->phy, priv);
234
235 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
236 if (IS_ERR(provider))
237 return PTR_ERR(provider);
238
239 dev_set_drvdata(priv->dev, priv);
240 return 0;
241}
242
243static struct platform_driver ltq_rcu_usb2_phy_driver = {
244 .probe = ltq_rcu_usb2_phy_probe,
245 .driver = {
246 .name = "lantiq-rcu-usb2-phy",
247 .of_match_table = ltq_rcu_usb2_phy_of_match,
248 }
249};
250module_platform_driver(ltq_rcu_usb2_phy_driver);
251
252MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
253MODULE_DESCRIPTION("Lantiq XWAY USB2 PHY driver");
254MODULE_LICENSE("GPL v2");
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 52d5251660b9..e0c393214264 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -47,6 +47,12 @@ config RESET_IMX7
47 help 47 help
48 This enables the reset controller driver for i.MX7 SoCs. 48 This enables the reset controller driver for i.MX7 SoCs.
49 49
50config RESET_LANTIQ
51 bool "Lantiq XWAY Reset Driver" if COMPILE_TEST
52 default SOC_TYPE_XWAY
53 help
54 This enables the reset controller driver for Lantiq / Intel XWAY SoCs.
55
50config RESET_LPC18XX 56config RESET_LPC18XX
51 bool "LPC18xx/43xx Reset Driver" if COMPILE_TEST 57 bool "LPC18xx/43xx Reset Driver" if COMPILE_TEST
52 default ARCH_LPC18XX 58 default ARCH_LPC18XX
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index b62783f50fe5..d368367110e5 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
7obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o 7obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
8obj-$(CONFIG_RESET_HSDK_V1) += reset-hsdk-v1.o 8obj-$(CONFIG_RESET_HSDK_V1) += reset-hsdk-v1.o
9obj-$(CONFIG_RESET_IMX7) += reset-imx7.o 9obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
10obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
10obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o 11obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
11obj-$(CONFIG_RESET_MESON) += reset-meson.o 12obj-$(CONFIG_RESET_MESON) += reset-meson.o
12obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o 13obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
diff --git a/drivers/reset/reset-lantiq.c b/drivers/reset/reset-lantiq.c
new file mode 100644
index 000000000000..11a582e50d30
--- /dev/null
+++ b/drivers/reset/reset-lantiq.c
@@ -0,0 +1,212 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@phrozen.org>
7 * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
8 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
9 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
10 */
11
12#include <linux/mfd/syscon.h>
13#include <linux/module.h>
14#include <linux/regmap.h>
15#include <linux/reset-controller.h>
16#include <linux/of_address.h>
17#include <linux/of_platform.h>
18#include <linux/platform_device.h>
19#include <linux/property.h>
20
21#define LANTIQ_RCU_RESET_TIMEOUT 10000
22
23struct lantiq_rcu_reset_priv {
24 struct reset_controller_dev rcdev;
25 struct device *dev;
26 struct regmap *regmap;
27 u32 reset_offset;
28 u32 status_offset;
29};
30
31static struct lantiq_rcu_reset_priv *to_lantiq_rcu_reset_priv(
32 struct reset_controller_dev *rcdev)
33{
34 return container_of(rcdev, struct lantiq_rcu_reset_priv, rcdev);
35}
36
37static int lantiq_rcu_reset_status(struct reset_controller_dev *rcdev,
38 unsigned long id)
39{
40 struct lantiq_rcu_reset_priv *priv = to_lantiq_rcu_reset_priv(rcdev);
41 unsigned int status = (id >> 8) & 0x1f;
42 u32 val;
43 int ret;
44
45 ret = regmap_read(priv->regmap, priv->status_offset, &val);
46 if (ret)
47 return ret;
48
49 return !!(val & BIT(status));
50}
51
52static int lantiq_rcu_reset_status_timeout(struct reset_controller_dev *rcdev,
53 unsigned long id, bool assert)
54{
55 int ret;
56 int retry = LANTIQ_RCU_RESET_TIMEOUT;
57
58 do {
59 ret = lantiq_rcu_reset_status(rcdev, id);
60 if (ret < 0)
61 return ret;
62 if (ret == assert)
63 return 0;
64 usleep_range(20, 40);
65 } while (--retry);
66
67 return -ETIMEDOUT;
68}
69
70static int lantiq_rcu_reset_update(struct reset_controller_dev *rcdev,
71 unsigned long id, bool assert)
72{
73 struct lantiq_rcu_reset_priv *priv = to_lantiq_rcu_reset_priv(rcdev);
74 unsigned int set = id & 0x1f;
75 u32 val = assert ? BIT(set) : 0;
76 int ret;
77
78 ret = regmap_update_bits(priv->regmap, priv->reset_offset, BIT(set),
79 val);
80 if (ret) {
81 dev_err(priv->dev, "Failed to set reset bit %u\n", set);
82 return ret;
83 }
84
85
86 ret = lantiq_rcu_reset_status_timeout(rcdev, id, assert);
87 if (ret)
88 dev_err(priv->dev, "Failed to %s bit %u\n",
89 assert ? "assert" : "deassert", set);
90
91 return ret;
92}
93
94static int lantiq_rcu_reset_assert(struct reset_controller_dev *rcdev,
95 unsigned long id)
96{
97 return lantiq_rcu_reset_update(rcdev, id, true);
98}
99
100static int lantiq_rcu_reset_deassert(struct reset_controller_dev *rcdev,
101 unsigned long id)
102{
103 return lantiq_rcu_reset_update(rcdev, id, false);
104}
105
106static int lantiq_rcu_reset_reset(struct reset_controller_dev *rcdev,
107 unsigned long id)
108{
109 int ret;
110
111 ret = lantiq_rcu_reset_assert(rcdev, id);
112 if (ret)
113 return ret;
114
115 return lantiq_rcu_reset_deassert(rcdev, id);
116}
117
118static const struct reset_control_ops lantiq_rcu_reset_ops = {
119 .assert = lantiq_rcu_reset_assert,
120 .deassert = lantiq_rcu_reset_deassert,
121 .status = lantiq_rcu_reset_status,
122 .reset = lantiq_rcu_reset_reset,
123};
124
125static int lantiq_rcu_reset_of_parse(struct platform_device *pdev,
126 struct lantiq_rcu_reset_priv *priv)
127{
128 struct device *dev = &pdev->dev;
129 const __be32 *offset;
130
131 priv->regmap = syscon_node_to_regmap(dev->of_node->parent);
132 if (IS_ERR(priv->regmap)) {
133 dev_err(&pdev->dev, "Failed to lookup RCU regmap\n");
134 return PTR_ERR(priv->regmap);
135 }
136
137 offset = of_get_address(dev->of_node, 0, NULL, NULL);
138 if (!offset) {
139 dev_err(&pdev->dev, "Failed to get RCU reset offset\n");
140 return -ENOENT;
141 }
142 priv->reset_offset = __be32_to_cpu(*offset);
143
144 offset = of_get_address(dev->of_node, 1, NULL, NULL);
145 if (!offset) {
146 dev_err(&pdev->dev, "Failed to get RCU status offset\n");
147 return -ENOENT;
148 }
149 priv->status_offset = __be32_to_cpu(*offset);
150
151 return 0;
152}
153
154static int lantiq_rcu_reset_xlate(struct reset_controller_dev *rcdev,
155 const struct of_phandle_args *reset_spec)
156{
157 unsigned int status, set;
158
159 set = reset_spec->args[0];
160 status = reset_spec->args[1];
161
162 if (set >= rcdev->nr_resets || status >= rcdev->nr_resets)
163 return -EINVAL;
164
165 return (status << 8) | set;
166}
167
168static int lantiq_rcu_reset_probe(struct platform_device *pdev)
169{
170 struct lantiq_rcu_reset_priv *priv;
171 int err;
172
173 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
174 if (!priv)
175 return -ENOMEM;
176
177 priv->dev = &pdev->dev;
178 platform_set_drvdata(pdev, priv);
179
180 err = lantiq_rcu_reset_of_parse(pdev, priv);
181 if (err)
182 return err;
183
184 priv->rcdev.ops = &lantiq_rcu_reset_ops;
185 priv->rcdev.owner = THIS_MODULE;
186 priv->rcdev.of_node = pdev->dev.of_node;
187 priv->rcdev.nr_resets = 32;
188 priv->rcdev.of_xlate = lantiq_rcu_reset_xlate;
189 priv->rcdev.of_reset_n_cells = 2;
190
191 return reset_controller_register(&priv->rcdev);
192}
193
194static const struct of_device_id lantiq_rcu_reset_dt_ids[] = {
195 { .compatible = "lantiq,danube-reset", },
196 { .compatible = "lantiq,xrx200-reset", },
197 { },
198};
199MODULE_DEVICE_TABLE(of, lantiq_rcu_reset_dt_ids);
200
201static struct platform_driver lantiq_rcu_reset_driver = {
202 .probe = lantiq_rcu_reset_probe,
203 .driver = {
204 .name = "lantiq-reset",
205 .of_match_table = lantiq_rcu_reset_dt_ids,
206 },
207};
208module_platform_driver(lantiq_rcu_reset_driver);
209
210MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
211MODULE_DESCRIPTION("Lantiq XWAY RCU Reset Controller Driver");
212MODULE_LICENSE("GPL");
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 280a6a91a9e2..2fcaff864584 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_ARCH_DOVE) += dove/
9obj-$(CONFIG_MACH_DOVE) += dove/ 9obj-$(CONFIG_MACH_DOVE) += dove/
10obj-y += fsl/ 10obj-y += fsl/
11obj-$(CONFIG_ARCH_MXC) += imx/ 11obj-$(CONFIG_ARCH_MXC) += imx/
12obj-$(CONFIG_SOC_XWAY) += lantiq/
12obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ 13obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
13obj-$(CONFIG_ARCH_MESON) += amlogic/ 14obj-$(CONFIG_ARCH_MESON) += amlogic/
14obj-$(CONFIG_ARCH_QCOM) += qcom/ 15obj-$(CONFIG_ARCH_QCOM) += qcom/
diff --git a/drivers/soc/lantiq/Makefile b/drivers/soc/lantiq/Makefile
new file mode 100644
index 000000000000..be9e866d53e5
--- /dev/null
+++ b/drivers/soc/lantiq/Makefile
@@ -0,0 +1,2 @@
1obj-y += fpi-bus.o
2obj-$(CONFIG_XRX200_PHY_FW) += gphy.o
diff --git a/drivers/soc/lantiq/fpi-bus.c b/drivers/soc/lantiq/fpi-bus.c
new file mode 100644
index 000000000000..a671c9984c4c
--- /dev/null
+++ b/drivers/soc/lantiq/fpi-bus.c
@@ -0,0 +1,87 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011-2015 John Crispin <blogic@phrozen.org>
7 * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
8 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
9 */
10
11#include <linux/device.h>
12#include <linux/err.h>
13#include <linux/mfd/syscon.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/of_platform.h>
17#include <linux/platform_device.h>
18#include <linux/property.h>
19#include <linux/regmap.h>
20
21#include <lantiq_soc.h>
22
23#define XBAR_ALWAYS_LAST 0x430
24#define XBAR_FPI_BURST_EN BIT(1)
25#define XBAR_AHB_BURST_EN BIT(2)
26
27#define RCU_VR9_BE_AHB1S 0x00000008
28
29static int ltq_fpi_probe(struct platform_device *pdev)
30{
31 struct device *dev = &pdev->dev;
32 struct device_node *np = dev->of_node;
33 struct resource *res_xbar;
34 struct regmap *rcu_regmap;
35 void __iomem *xbar_membase;
36 u32 rcu_ahb_endianness_reg_offset;
37 int ret;
38
39 res_xbar = platform_get_resource(pdev, IORESOURCE_MEM, 0);
40 xbar_membase = devm_ioremap_resource(dev, res_xbar);
41 if (IS_ERR(xbar_membase))
42 return PTR_ERR(xbar_membase);
43
44 /* RCU configuration is optional */
45 rcu_regmap = syscon_regmap_lookup_by_phandle(np, "lantiq,rcu");
46 if (IS_ERR(rcu_regmap))
47 return PTR_ERR(rcu_regmap);
48
49 ret = device_property_read_u32(dev, "lantiq,offset-endianness",
50 &rcu_ahb_endianness_reg_offset);
51 if (ret) {
52 dev_err(&pdev->dev, "Failed to get RCU reg offset\n");
53 return ret;
54 }
55
56 ret = regmap_update_bits(rcu_regmap, rcu_ahb_endianness_reg_offset,
57 RCU_VR9_BE_AHB1S, RCU_VR9_BE_AHB1S);
58 if (ret) {
59 dev_warn(&pdev->dev,
60 "Failed to configure RCU AHB endianness\n");
61 return ret;
62 }
63
64 /* disable fpi burst */
65 ltq_w32_mask(XBAR_FPI_BURST_EN, 0, xbar_membase + XBAR_ALWAYS_LAST);
66
67 return of_platform_populate(dev->of_node, NULL, NULL, dev);
68}
69
70static const struct of_device_id ltq_fpi_match[] = {
71 { .compatible = "lantiq,xrx200-fpi" },
72 {},
73};
74MODULE_DEVICE_TABLE(of, ltq_fpi_match);
75
76static struct platform_driver ltq_fpi_driver = {
77 .probe = ltq_fpi_probe,
78 .driver = {
79 .name = "fpi-xway",
80 .of_match_table = ltq_fpi_match,
81 },
82};
83
84module_platform_driver(ltq_fpi_driver);
85
86MODULE_DESCRIPTION("Lantiq FPI bus driver");
87MODULE_LICENSE("GPL");
diff --git a/drivers/soc/lantiq/gphy.c b/drivers/soc/lantiq/gphy.c
new file mode 100644
index 000000000000..8d8659463b3e
--- /dev/null
+++ b/drivers/soc/lantiq/gphy.c
@@ -0,0 +1,260 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 John Crispin <blogic@phrozen.org>
7 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
8 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
9 */
10
11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/dma-mapping.h>
14#include <linux/firmware.h>
15#include <linux/mfd/syscon.h>
16#include <linux/module.h>
17#include <linux/reboot.h>
18#include <linux/regmap.h>
19#include <linux/reset.h>
20#include <linux/of_device.h>
21#include <linux/of_platform.h>
22#include <linux/property.h>
23#include <dt-bindings/mips/lantiq_rcu_gphy.h>
24
25#include <lantiq_soc.h>
26
27#define XRX200_GPHY_FW_ALIGN (16 * 1024)
28
29struct xway_gphy_priv {
30 struct clk *gphy_clk_gate;
31 struct reset_control *gphy_reset;
32 struct reset_control *gphy_reset2;
33 struct notifier_block gphy_reboot_nb;
34 void __iomem *membase;
35 char *fw_name;
36};
37
38struct xway_gphy_match_data {
39 char *fe_firmware_name;
40 char *ge_firmware_name;
41};
42
43static const struct xway_gphy_match_data xrx200a1x_gphy_data = {
44 .fe_firmware_name = "lantiq/xrx200_phy22f_a14.bin",
45 .ge_firmware_name = "lantiq/xrx200_phy11g_a14.bin",
46};
47
48static const struct xway_gphy_match_data xrx200a2x_gphy_data = {
49 .fe_firmware_name = "lantiq/xrx200_phy22f_a22.bin",
50 .ge_firmware_name = "lantiq/xrx200_phy11g_a22.bin",
51};
52
53static const struct xway_gphy_match_data xrx300_gphy_data = {
54 .fe_firmware_name = "lantiq/xrx300_phy22f_a21.bin",
55 .ge_firmware_name = "lantiq/xrx300_phy11g_a21.bin",
56};
57
58static const struct of_device_id xway_gphy_match[] = {
59 { .compatible = "lantiq,xrx200a1x-gphy", .data = &xrx200a1x_gphy_data },
60 { .compatible = "lantiq,xrx200a2x-gphy", .data = &xrx200a2x_gphy_data },
61 { .compatible = "lantiq,xrx300-gphy", .data = &xrx300_gphy_data },
62 { .compatible = "lantiq,xrx330-gphy", .data = &xrx300_gphy_data },
63 {},
64};
65MODULE_DEVICE_TABLE(of, xway_gphy_match);
66
67static struct xway_gphy_priv *to_xway_gphy_priv(struct notifier_block *nb)
68{
69 return container_of(nb, struct xway_gphy_priv, gphy_reboot_nb);
70}
71
72static int xway_gphy_reboot_notify(struct notifier_block *reboot_nb,
73 unsigned long code, void *unused)
74{
75 struct xway_gphy_priv *priv = to_xway_gphy_priv(reboot_nb);
76
77 if (priv) {
78 reset_control_assert(priv->gphy_reset);
79 reset_control_assert(priv->gphy_reset2);
80 }
81
82 return NOTIFY_DONE;
83}
84
85static int xway_gphy_load(struct device *dev, struct xway_gphy_priv *priv,
86 dma_addr_t *dev_addr)
87{
88 const struct firmware *fw;
89 void *fw_addr;
90 dma_addr_t dma_addr;
91 size_t size;
92 int ret;
93
94 ret = request_firmware(&fw, priv->fw_name, dev);
95 if (ret) {
96 dev_err(dev, "failed to load firmware: %s, error: %i\n",
97 priv->fw_name, ret);
98 return ret;
99 }
100
101 /*
102 * GPHY cores need the firmware code in a persistent and contiguous
103 * memory area with a 16 kB boundary aligned start address.
104 */
105 size = fw->size + XRX200_GPHY_FW_ALIGN;
106
107 fw_addr = dmam_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL);
108 if (fw_addr) {
109 fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN);
110 *dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
111 memcpy(fw_addr, fw->data, fw->size);
112 } else {
113 dev_err(dev, "failed to alloc firmware memory\n");
114 ret = -ENOMEM;
115 }
116
117 release_firmware(fw);
118
119 return ret;
120}
121
122static int xway_gphy_of_probe(struct platform_device *pdev,
123 struct xway_gphy_priv *priv)
124{
125 struct device *dev = &pdev->dev;
126 const struct xway_gphy_match_data *gphy_fw_name_cfg;
127 u32 gphy_mode;
128 int ret;
129 struct resource *res_gphy;
130
131 gphy_fw_name_cfg = of_device_get_match_data(dev);
132
133 priv->gphy_clk_gate = devm_clk_get(dev, NULL);
134 if (IS_ERR(priv->gphy_clk_gate)) {
135 dev_err(dev, "Failed to lookup gate clock\n");
136 return PTR_ERR(priv->gphy_clk_gate);
137 }
138
139 res_gphy = platform_get_resource(pdev, IORESOURCE_MEM, 0);
140 priv->membase = devm_ioremap_resource(dev, res_gphy);
141 if (IS_ERR(priv->membase))
142 return PTR_ERR(priv->membase);
143
144 priv->gphy_reset = devm_reset_control_get(dev, "gphy");
145 if (IS_ERR(priv->gphy_reset)) {
146 if (PTR_ERR(priv->gphy_reset) != -EPROBE_DEFER)
147 dev_err(dev, "Failed to lookup gphy reset\n");
148 return PTR_ERR(priv->gphy_reset);
149 }
150
151 priv->gphy_reset2 = devm_reset_control_get_optional(dev, "gphy2");
152 if (IS_ERR(priv->gphy_reset2))
153 return PTR_ERR(priv->gphy_reset2);
154
155 ret = device_property_read_u32(dev, "lantiq,gphy-mode", &gphy_mode);
156 /* Default to GE mode */
157 if (ret)
158 gphy_mode = GPHY_MODE_GE;
159
160 switch (gphy_mode) {
161 case GPHY_MODE_FE:
162 priv->fw_name = gphy_fw_name_cfg->fe_firmware_name;
163 break;
164 case GPHY_MODE_GE:
165 priv->fw_name = gphy_fw_name_cfg->ge_firmware_name;
166 break;
167 default:
168 dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
169 return -EINVAL;
170 }
171
172 return 0;
173}
174
175static int xway_gphy_probe(struct platform_device *pdev)
176{
177 struct device *dev = &pdev->dev;
178 struct xway_gphy_priv *priv;
179 dma_addr_t fw_addr = 0;
180 int ret;
181
182 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
183 if (!priv)
184 return -ENOMEM;
185
186 ret = xway_gphy_of_probe(pdev, priv);
187 if (ret)
188 return ret;
189
190 ret = clk_prepare_enable(priv->gphy_clk_gate);
191 if (ret)
192 return ret;
193
194 ret = xway_gphy_load(dev, priv, &fw_addr);
195 if (ret) {
196 clk_disable_unprepare(priv->gphy_clk_gate);
197 return ret;
198 }
199
200 reset_control_assert(priv->gphy_reset);
201 reset_control_assert(priv->gphy_reset2);
202
203 iowrite32be(fw_addr, priv->membase);
204
205 reset_control_deassert(priv->gphy_reset);
206 reset_control_deassert(priv->gphy_reset2);
207
208 /* assert the gphy reset because it can hang after a reboot: */
209 priv->gphy_reboot_nb.notifier_call = xway_gphy_reboot_notify;
210 priv->gphy_reboot_nb.priority = -1;
211
212 ret = register_reboot_notifier(&priv->gphy_reboot_nb);
213 if (ret)
214 dev_warn(dev, "Failed to register reboot notifier\n");
215
216 platform_set_drvdata(pdev, priv);
217
218 return ret;
219}
220
221static int xway_gphy_remove(struct platform_device *pdev)
222{
223 struct device *dev = &pdev->dev;
224 struct xway_gphy_priv *priv = platform_get_drvdata(pdev);
225 int ret;
226
227 reset_control_assert(priv->gphy_reset);
228 reset_control_assert(priv->gphy_reset2);
229
230 iowrite32be(0, priv->membase);
231
232 clk_disable_unprepare(priv->gphy_clk_gate);
233
234 ret = unregister_reboot_notifier(&priv->gphy_reboot_nb);
235 if (ret)
236 dev_warn(dev, "Failed to unregister reboot notifier\n");
237
238 return 0;
239}
240
241static struct platform_driver xway_gphy_driver = {
242 .probe = xway_gphy_probe,
243 .remove = xway_gphy_remove,
244 .driver = {
245 .name = "xway-rcu-gphy",
246 .of_match_table = xway_gphy_match,
247 },
248};
249
250module_platform_driver(xway_gphy_driver);
251
252MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin");
253MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin");
254MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin");
255MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin");
256MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin");
257MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin");
258MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
259MODULE_DESCRIPTION("Lantiq XWAY GPHY Firmware Loader");
260MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
index e0823677d8c1..7f43cefa0eae 100644
--- a/drivers/watchdog/lantiq_wdt.c
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -4,6 +4,7 @@
4 * by the Free Software Foundation. 4 * by the Free Software Foundation.
5 * 5 *
6 * Copyright (C) 2010 John Crispin <john@phrozen.org> 6 * Copyright (C) 2010 John Crispin <john@phrozen.org>
7 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
7 * Based on EP93xx wdt driver 8 * Based on EP93xx wdt driver
8 */ 9 */
9 10
@@ -17,9 +18,20 @@
17#include <linux/uaccess.h> 18#include <linux/uaccess.h>
18#include <linux/clk.h> 19#include <linux/clk.h>
19#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/regmap.h>
22#include <linux/mfd/syscon.h>
20 23
21#include <lantiq_soc.h> 24#include <lantiq_soc.h>
22 25
26#define LTQ_XRX_RCU_RST_STAT 0x0014
27#define LTQ_XRX_RCU_RST_STAT_WDT BIT(31)
28
29/* CPU0 Reset Source Register */
30#define LTQ_FALCON_SYS1_CPU0RS 0x0060
31/* reset cause mask */
32#define LTQ_FALCON_SYS1_CPU0RS_MASK 0x0007
33#define LTQ_FALCON_SYS1_CPU0RS_WDT 0x02
34
23/* 35/*
24 * Section 3.4 of the datasheet 36 * Section 3.4 of the datasheet
25 * The password sequence protects the WDT control register from unintended 37 * The password sequence protects the WDT control register from unintended
@@ -186,16 +198,70 @@ static struct miscdevice ltq_wdt_miscdev = {
186 .fops = &ltq_wdt_fops, 198 .fops = &ltq_wdt_fops,
187}; 199};
188 200
201typedef int (*ltq_wdt_bootstatus_set)(struct platform_device *pdev);
202
203static int ltq_wdt_bootstatus_xrx(struct platform_device *pdev)
204{
205 struct device *dev = &pdev->dev;
206 struct regmap *rcu_regmap;
207 u32 val;
208 int err;
209
210 rcu_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
211 if (IS_ERR(rcu_regmap))
212 return PTR_ERR(rcu_regmap);
213
214 err = regmap_read(rcu_regmap, LTQ_XRX_RCU_RST_STAT, &val);
215 if (err)
216 return err;
217
218 if (val & LTQ_XRX_RCU_RST_STAT_WDT)
219 ltq_wdt_bootstatus = WDIOF_CARDRESET;
220
221 return 0;
222}
223
224static int ltq_wdt_bootstatus_falcon(struct platform_device *pdev)
225{
226 struct device *dev = &pdev->dev;
227 struct regmap *rcu_regmap;
228 u32 val;
229 int err;
230
231 rcu_regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
232 "lantiq,rcu");
233 if (IS_ERR(rcu_regmap))
234 return PTR_ERR(rcu_regmap);
235
236 err = regmap_read(rcu_regmap, LTQ_FALCON_SYS1_CPU0RS, &val);
237 if (err)
238 return err;
239
240 if ((val & LTQ_FALCON_SYS1_CPU0RS_MASK) == LTQ_FALCON_SYS1_CPU0RS_WDT)
241 ltq_wdt_bootstatus = WDIOF_CARDRESET;
242
243 return 0;
244}
245
189static int 246static int
190ltq_wdt_probe(struct platform_device *pdev) 247ltq_wdt_probe(struct platform_device *pdev)
191{ 248{
192 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 249 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
193 struct clk *clk; 250 struct clk *clk;
251 ltq_wdt_bootstatus_set ltq_wdt_bootstatus_set;
252 int ret;
194 253
195 ltq_wdt_membase = devm_ioremap_resource(&pdev->dev, res); 254 ltq_wdt_membase = devm_ioremap_resource(&pdev->dev, res);
196 if (IS_ERR(ltq_wdt_membase)) 255 if (IS_ERR(ltq_wdt_membase))
197 return PTR_ERR(ltq_wdt_membase); 256 return PTR_ERR(ltq_wdt_membase);
198 257
258 ltq_wdt_bootstatus_set = of_device_get_match_data(&pdev->dev);
259 if (ltq_wdt_bootstatus_set) {
260 ret = ltq_wdt_bootstatus_set(pdev);
261 if (ret)
262 return ret;
263 }
264
199 /* we do not need to enable the clock as it is always running */ 265 /* we do not need to enable the clock as it is always running */
200 clk = clk_get_io(); 266 clk = clk_get_io();
201 if (IS_ERR(clk)) { 267 if (IS_ERR(clk)) {
@@ -205,10 +271,6 @@ ltq_wdt_probe(struct platform_device *pdev)
205 ltq_io_region_clk_rate = clk_get_rate(clk); 271 ltq_io_region_clk_rate = clk_get_rate(clk);
206 clk_put(clk); 272 clk_put(clk);
207 273
208 /* find out if the watchdog caused the last reboot */
209 if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST)
210 ltq_wdt_bootstatus = WDIOF_CARDRESET;
211
212 dev_info(&pdev->dev, "Init done\n"); 274 dev_info(&pdev->dev, "Init done\n");
213 return misc_register(&ltq_wdt_miscdev); 275 return misc_register(&ltq_wdt_miscdev);
214} 276}
@@ -222,7 +284,9 @@ ltq_wdt_remove(struct platform_device *pdev)
222} 284}
223 285
224static const struct of_device_id ltq_wdt_match[] = { 286static const struct of_device_id ltq_wdt_match[] = {
225 { .compatible = "lantiq,wdt" }, 287 { .compatible = "lantiq,wdt", .data = NULL},
288 { .compatible = "lantiq,xrx100-wdt", .data = ltq_wdt_bootstatus_xrx },
289 { .compatible = "lantiq,falcon-wdt", .data = ltq_wdt_bootstatus_falcon },
226 {}, 290 {},
227}; 291};
228MODULE_DEVICE_TABLE(of, ltq_wdt_match); 292MODULE_DEVICE_TABLE(of, ltq_wdt_match);
diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c
index b5cdceb36cff..0ec419a3f7ed 100644
--- a/drivers/watchdog/octeon-wdt-main.c
+++ b/drivers/watchdog/octeon-wdt-main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Octeon Watchdog driver 2 * Octeon Watchdog driver
3 * 3 *
4 * Copyright (C) 2007, 2008, 2009, 2010 Cavium Networks 4 * Copyright (C) 2007-2017 Cavium, Inc.
5 * 5 *
6 * Converted to use WATCHDOG_CORE by Aaro Koskinen <aaro.koskinen@iki.fi>. 6 * Converted to use WATCHDOG_CORE by Aaro Koskinen <aaro.koskinen@iki.fi>.
7 * 7 *
@@ -59,20 +59,23 @@
59#include <linux/interrupt.h> 59#include <linux/interrupt.h>
60#include <linux/watchdog.h> 60#include <linux/watchdog.h>
61#include <linux/cpumask.h> 61#include <linux/cpumask.h>
62#include <linux/bitops.h>
63#include <linux/kernel.h>
64#include <linux/module.h> 62#include <linux/module.h>
65#include <linux/string.h>
66#include <linux/delay.h> 63#include <linux/delay.h>
67#include <linux/cpu.h> 64#include <linux/cpu.h>
68#include <linux/smp.h>
69#include <linux/fs.h>
70#include <linux/irq.h> 65#include <linux/irq.h>
71 66
72#include <asm/mipsregs.h> 67#include <asm/mipsregs.h>
73#include <asm/uasm.h> 68#include <asm/uasm.h>
74 69
75#include <asm/octeon/octeon.h> 70#include <asm/octeon/octeon.h>
71#include <asm/octeon/cvmx-boot-vector.h>
72#include <asm/octeon/cvmx-ciu2-defs.h>
73#include <asm/octeon/cvmx-rst-defs.h>
74
75/* Watchdog interrupt major block number (8 MSBs of intsn) */
76#define WD_BLOCK_NUMBER 0x01
77
78static int divisor;
76 79
77/* The count needed to achieve timeout_sec. */ 80/* The count needed to achieve timeout_sec. */
78static unsigned int timeout_cnt; 81static unsigned int timeout_cnt;
@@ -84,7 +87,7 @@ static unsigned int max_timeout_sec;
84static unsigned int timeout_sec; 87static unsigned int timeout_sec;
85 88
86/* Set to non-zero when userspace countdown mode active */ 89/* Set to non-zero when userspace countdown mode active */
87static int do_coundown; 90static bool do_countdown;
88static unsigned int countdown_reset; 91static unsigned int countdown_reset;
89static unsigned int per_cpu_countdown[NR_CPUS]; 92static unsigned int per_cpu_countdown[NR_CPUS];
90 93
@@ -92,152 +95,38 @@ static cpumask_t irq_enabled_cpus;
92 95
93#define WD_TIMO 60 /* Default heartbeat = 60 seconds */ 96#define WD_TIMO 60 /* Default heartbeat = 60 seconds */
94 97
98#define CVMX_GSERX_SCRATCH(offset) (CVMX_ADD_IO_SEG(0x0001180090000020ull) + ((offset) & 15) * 0x1000000ull)
99
95static int heartbeat = WD_TIMO; 100static int heartbeat = WD_TIMO;
96module_param(heartbeat, int, S_IRUGO); 101module_param(heartbeat, int, 0444);
97MODULE_PARM_DESC(heartbeat, 102MODULE_PARM_DESC(heartbeat,
98 "Watchdog heartbeat in seconds. (0 < heartbeat, default=" 103 "Watchdog heartbeat in seconds. (0 < heartbeat, default="
99 __MODULE_STRING(WD_TIMO) ")"); 104 __MODULE_STRING(WD_TIMO) ")");
100 105
101static bool nowayout = WATCHDOG_NOWAYOUT; 106static bool nowayout = WATCHDOG_NOWAYOUT;
102module_param(nowayout, bool, S_IRUGO); 107module_param(nowayout, bool, 0444);
103MODULE_PARM_DESC(nowayout, 108MODULE_PARM_DESC(nowayout,
104 "Watchdog cannot be stopped once started (default=" 109 "Watchdog cannot be stopped once started (default="
105 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 110 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
106 111
107static u32 nmi_stage1_insns[64] __initdata; 112static int disable;
108/* We need one branch and therefore one relocation per target label. */ 113module_param(disable, int, 0444);
109static struct uasm_label labels[5] __initdata; 114MODULE_PARM_DESC(disable,
110static struct uasm_reloc relocs[5] __initdata; 115 "Disable the watchdog entirely (default=0)");
111
112enum lable_id {
113 label_enter_bootloader = 1
114};
115 116
116/* Some CP0 registers */ 117static struct cvmx_boot_vector_element *octeon_wdt_bootvector;
117#define K0 26
118#define C0_CVMMEMCTL 11, 7
119#define C0_STATUS 12, 0
120#define C0_EBASE 15, 1
121#define C0_DESAVE 31, 0
122 118
123void octeon_wdt_nmi_stage2(void); 119void octeon_wdt_nmi_stage2(void);
124 120
125static void __init octeon_wdt_build_stage1(void)
126{
127 int i;
128 int len;
129 u32 *p = nmi_stage1_insns;
130#ifdef CONFIG_HOTPLUG_CPU
131 struct uasm_label *l = labels;
132 struct uasm_reloc *r = relocs;
133#endif
134
135 /*
136 * For the next few instructions running the debugger may
137 * cause corruption of k0 in the saved registers. Since we're
138 * about to crash, nobody probably cares.
139 *
140 * Save K0 into the debug scratch register
141 */
142 uasm_i_dmtc0(&p, K0, C0_DESAVE);
143
144 uasm_i_mfc0(&p, K0, C0_STATUS);
145#ifdef CONFIG_HOTPLUG_CPU
146 if (octeon_bootloader_entry_addr)
147 uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI),
148 label_enter_bootloader);
149#endif
150 /* Force 64-bit addressing enabled */
151 uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX);
152 uasm_i_mtc0(&p, K0, C0_STATUS);
153
154#ifdef CONFIG_HOTPLUG_CPU
155 if (octeon_bootloader_entry_addr) {
156 uasm_i_mfc0(&p, K0, C0_EBASE);
157 /* Coreid number in K0 */
158 uasm_i_andi(&p, K0, K0, 0xf);
159 /* 8 * coreid in bits 16-31 */
160 uasm_i_dsll_safe(&p, K0, K0, 3 + 16);
161 uasm_i_ori(&p, K0, K0, 0x8001);
162 uasm_i_dsll_safe(&p, K0, K0, 16);
163 uasm_i_ori(&p, K0, K0, 0x0700);
164 uasm_i_drotr_safe(&p, K0, K0, 32);
165 /*
166 * Should result in: 0x8001,0700,0000,8*coreid which is
167 * CVMX_CIU_WDOGX(coreid) - 0x0500
168 *
169 * Now ld K0, CVMX_CIU_WDOGX(coreid)
170 */
171 uasm_i_ld(&p, K0, 0x500, K0);
172 /*
173 * If bit one set handle the NMI as a watchdog event.
174 * otherwise transfer control to bootloader.
175 */
176 uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader);
177 uasm_i_nop(&p);
178 }
179#endif
180
181 /* Clear Dcache so cvmseg works right. */
182 uasm_i_cache(&p, 1, 0, 0);
183
184 /* Use K0 to do a read/modify/write of CVMMEMCTL */
185 uasm_i_dmfc0(&p, K0, C0_CVMMEMCTL);
186 /* Clear out the size of CVMSEG */
187 uasm_i_dins(&p, K0, 0, 0, 6);
188 /* Set CVMSEG to its largest value */
189 uasm_i_ori(&p, K0, K0, 0x1c0 | 54);
190 /* Store the CVMMEMCTL value */
191 uasm_i_dmtc0(&p, K0, C0_CVMMEMCTL);
192
193 /* Load the address of the second stage handler */
194 UASM_i_LA(&p, K0, (long)octeon_wdt_nmi_stage2);
195 uasm_i_jr(&p, K0);
196 uasm_i_dmfc0(&p, K0, C0_DESAVE);
197
198#ifdef CONFIG_HOTPLUG_CPU
199 if (octeon_bootloader_entry_addr) {
200 uasm_build_label(&l, p, label_enter_bootloader);
201 /* Jump to the bootloader and restore K0 */
202 UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr);
203 uasm_i_jr(&p, K0);
204 uasm_i_dmfc0(&p, K0, C0_DESAVE);
205 }
206#endif
207 uasm_resolve_relocs(relocs, labels);
208
209 len = (int)(p - nmi_stage1_insns);
210 pr_debug("Synthesized NMI stage 1 handler (%d instructions)\n", len);
211
212 pr_debug("\t.set push\n");
213 pr_debug("\t.set noreorder\n");
214 for (i = 0; i < len; i++)
215 pr_debug("\t.word 0x%08x\n", nmi_stage1_insns[i]);
216 pr_debug("\t.set pop\n");
217
218 if (len > 32)
219 panic("NMI stage 1 handler exceeds 32 instructions, was %d\n",
220 len);
221}
222
223static int cpu2core(int cpu) 121static int cpu2core(int cpu)
224{ 122{
225#ifdef CONFIG_SMP 123#ifdef CONFIG_SMP
226 return cpu_logical_map(cpu); 124 return cpu_logical_map(cpu) & 0x3f;
227#else 125#else
228 return cvmx_get_core_num(); 126 return cvmx_get_core_num();
229#endif 127#endif
230} 128}
231 129
232static int core2cpu(int coreid)
233{
234#ifdef CONFIG_SMP
235 return cpu_number_map(coreid);
236#else
237 return 0;
238#endif
239}
240
241/** 130/**
242 * Poke the watchdog when an interrupt is received 131 * Poke the watchdog when an interrupt is received
243 * 132 *
@@ -248,13 +137,14 @@ static int core2cpu(int coreid)
248 */ 137 */
249static irqreturn_t octeon_wdt_poke_irq(int cpl, void *dev_id) 138static irqreturn_t octeon_wdt_poke_irq(int cpl, void *dev_id)
250{ 139{
251 unsigned int core = cvmx_get_core_num(); 140 int cpu = raw_smp_processor_id();
252 int cpu = core2cpu(core); 141 unsigned int core = cpu2core(cpu);
142 int node = cpu_to_node(cpu);
253 143
254 if (do_coundown) { 144 if (do_countdown) {
255 if (per_cpu_countdown[cpu] > 0) { 145 if (per_cpu_countdown[cpu] > 0) {
256 /* We're alive, poke the watchdog */ 146 /* We're alive, poke the watchdog */
257 cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1); 147 cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(core), 1);
258 per_cpu_countdown[cpu]--; 148 per_cpu_countdown[cpu]--;
259 } else { 149 } else {
260 /* Bad news, you are about to reboot. */ 150 /* Bad news, you are about to reboot. */
@@ -263,7 +153,7 @@ static irqreturn_t octeon_wdt_poke_irq(int cpl, void *dev_id)
263 } 153 }
264 } else { 154 } else {
265 /* Not open, just ping away... */ 155 /* Not open, just ping away... */
266 cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1); 156 cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(core), 1);
267 } 157 }
268 return IRQ_HANDLED; 158 return IRQ_HANDLED;
269} 159}
@@ -338,10 +228,10 @@ void octeon_wdt_nmi_stage3(u64 reg[32])
338 u64 cp0_epc = read_c0_epc(); 228 u64 cp0_epc = read_c0_epc();
339 229
340 /* Delay so output from all cores output is not jumbled together. */ 230 /* Delay so output from all cores output is not jumbled together. */
341 __delay(100000000ull * coreid); 231 udelay(85000 * coreid);
342 232
343 octeon_wdt_write_string("\r\n*** NMI Watchdog interrupt on Core 0x"); 233 octeon_wdt_write_string("\r\n*** NMI Watchdog interrupt on Core 0x");
344 octeon_wdt_write_hex(coreid, 1); 234 octeon_wdt_write_hex(coreid, 2);
345 octeon_wdt_write_string(" ***\r\n"); 235 octeon_wdt_write_string(" ***\r\n");
346 for (i = 0; i < 32; i++) { 236 for (i = 0; i < 32; i++) {
347 octeon_wdt_write_string("\t"); 237 octeon_wdt_write_string("\t");
@@ -364,33 +254,98 @@ void octeon_wdt_nmi_stage3(u64 reg[32])
364 octeon_wdt_write_hex(cp0_cause, 16); 254 octeon_wdt_write_hex(cp0_cause, 16);
365 octeon_wdt_write_string("\r\n"); 255 octeon_wdt_write_string("\r\n");
366 256
367 octeon_wdt_write_string("\tsum0\t0x"); 257 /* The CIU register is different for each Octeon model. */
368 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_SUM0(coreid * 2)), 16); 258 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
369 octeon_wdt_write_string("\ten0\t0x"); 259 octeon_wdt_write_string("\tsrc_wd\t0x");
370 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)), 16); 260 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_SRC_PPX_IP2_WDOG(coreid)), 16);
371 octeon_wdt_write_string("\r\n"); 261 octeon_wdt_write_string("\ten_wd\t0x");
262 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_EN_PPX_IP2_WDOG(coreid)), 16);
263 octeon_wdt_write_string("\r\n");
264 octeon_wdt_write_string("\tsrc_rml\t0x");
265 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_SRC_PPX_IP2_RML(coreid)), 16);
266 octeon_wdt_write_string("\ten_rml\t0x");
267 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_EN_PPX_IP2_RML(coreid)), 16);
268 octeon_wdt_write_string("\r\n");
269 octeon_wdt_write_string("\tsum\t0x");
270 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP2(coreid)), 16);
271 octeon_wdt_write_string("\r\n");
272 } else if (!octeon_has_feature(OCTEON_FEATURE_CIU3)) {
273 octeon_wdt_write_string("\tsum0\t0x");
274 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_SUM0(coreid * 2)), 16);
275 octeon_wdt_write_string("\ten0\t0x");
276 octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)), 16);
277 octeon_wdt_write_string("\r\n");
278 }
372 279
373 octeon_wdt_write_string("*** Chip soft reset soon ***\r\n"); 280 octeon_wdt_write_string("*** Chip soft reset soon ***\r\n");
281
282 /*
283 * G-30204: We must trigger a soft reset before watchdog
284 * does an incomplete job of doing it.
285 */
286 if (OCTEON_IS_OCTEON3() && !OCTEON_IS_MODEL(OCTEON_CN70XX)) {
287 u64 scr;
288 unsigned int node = cvmx_get_node_num();
289 unsigned int lcore = cvmx_get_local_core_num();
290 union cvmx_ciu_wdogx ciu_wdog;
291
292 /*
293 * Wait for other cores to print out information, but
294 * not too long. Do the soft reset before watchdog
295 * can trigger it.
296 */
297 do {
298 ciu_wdog.u64 = cvmx_read_csr_node(node, CVMX_CIU_WDOGX(lcore));
299 } while (ciu_wdog.s.cnt > 0x10000);
300
301 scr = cvmx_read_csr_node(0, CVMX_GSERX_SCRATCH(0));
302 scr |= 1 << 11; /* Indicate watchdog in bit 11 */
303 cvmx_write_csr_node(0, CVMX_GSERX_SCRATCH(0), scr);
304 cvmx_write_csr_node(0, CVMX_RST_SOFT_RST, 1);
305 }
306}
307
308static int octeon_wdt_cpu_to_irq(int cpu)
309{
310 unsigned int coreid;
311 int node;
312 int irq;
313
314 coreid = cpu2core(cpu);
315 node = cpu_to_node(cpu);
316
317 if (octeon_has_feature(OCTEON_FEATURE_CIU3)) {
318 struct irq_domain *domain;
319 int hwirq;
320
321 domain = octeon_irq_get_block_domain(node,
322 WD_BLOCK_NUMBER);
323 hwirq = WD_BLOCK_NUMBER << 12 | 0x200 | coreid;
324 irq = irq_find_mapping(domain, hwirq);
325 } else {
326 irq = OCTEON_IRQ_WDOG0 + coreid;
327 }
328 return irq;
374} 329}
375 330
376static int octeon_wdt_cpu_pre_down(unsigned int cpu) 331static int octeon_wdt_cpu_pre_down(unsigned int cpu)
377{ 332{
378 unsigned int core; 333 unsigned int core;
379 unsigned int irq; 334 int node;
380 union cvmx_ciu_wdogx ciu_wdog; 335 union cvmx_ciu_wdogx ciu_wdog;
381 336
382 core = cpu2core(cpu); 337 core = cpu2core(cpu);
383 338
384 irq = OCTEON_IRQ_WDOG0 + core; 339 node = cpu_to_node(cpu);
385 340
386 /* Poke the watchdog to clear out its state */ 341 /* Poke the watchdog to clear out its state */
387 cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1); 342 cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(core), 1);
388 343
389 /* Disable the hardware. */ 344 /* Disable the hardware. */
390 ciu_wdog.u64 = 0; 345 ciu_wdog.u64 = 0;
391 cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64); 346 cvmx_write_csr_node(node, CVMX_CIU_WDOGX(core), ciu_wdog.u64);
392 347
393 free_irq(irq, octeon_wdt_poke_irq); 348 free_irq(octeon_wdt_cpu_to_irq(cpu), octeon_wdt_poke_irq);
394 return 0; 349 return 0;
395} 350}
396 351
@@ -399,31 +354,56 @@ static int octeon_wdt_cpu_online(unsigned int cpu)
399 unsigned int core; 354 unsigned int core;
400 unsigned int irq; 355 unsigned int irq;
401 union cvmx_ciu_wdogx ciu_wdog; 356 union cvmx_ciu_wdogx ciu_wdog;
357 int node;
358 struct irq_domain *domain;
359 int hwirq;
402 360
403 core = cpu2core(cpu); 361 core = cpu2core(cpu);
362 node = cpu_to_node(cpu);
363
364 octeon_wdt_bootvector[core].target_ptr = (u64)octeon_wdt_nmi_stage2;
404 365
405 /* Disable it before doing anything with the interrupts. */ 366 /* Disable it before doing anything with the interrupts. */
406 ciu_wdog.u64 = 0; 367 ciu_wdog.u64 = 0;
407 cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64); 368 cvmx_write_csr_node(node, CVMX_CIU_WDOGX(core), ciu_wdog.u64);
408 369
409 per_cpu_countdown[cpu] = countdown_reset; 370 per_cpu_countdown[cpu] = countdown_reset;
410 371
411 irq = OCTEON_IRQ_WDOG0 + core; 372 if (octeon_has_feature(OCTEON_FEATURE_CIU3)) {
373 /* Must get the domain for the watchdog block */
374 domain = octeon_irq_get_block_domain(node, WD_BLOCK_NUMBER);
375
376 /* Get a irq for the wd intsn (hardware interrupt) */
377 hwirq = WD_BLOCK_NUMBER << 12 | 0x200 | core;
378 irq = irq_create_mapping(domain, hwirq);
379 irqd_set_trigger_type(irq_get_irq_data(irq),
380 IRQ_TYPE_EDGE_RISING);
381 } else
382 irq = OCTEON_IRQ_WDOG0 + core;
412 383
413 if (request_irq(irq, octeon_wdt_poke_irq, 384 if (request_irq(irq, octeon_wdt_poke_irq,
414 IRQF_NO_THREAD, "octeon_wdt", octeon_wdt_poke_irq)) 385 IRQF_NO_THREAD, "octeon_wdt", octeon_wdt_poke_irq))
415 panic("octeon_wdt: Couldn't obtain irq %d", irq); 386 panic("octeon_wdt: Couldn't obtain irq %d", irq);
416 387
388 /* Must set the irq affinity here */
389 if (octeon_has_feature(OCTEON_FEATURE_CIU3)) {
390 cpumask_t mask;
391
392 cpumask_clear(&mask);
393 cpumask_set_cpu(cpu, &mask);
394 irq_set_affinity(irq, &mask);
395 }
396
417 cpumask_set_cpu(cpu, &irq_enabled_cpus); 397 cpumask_set_cpu(cpu, &irq_enabled_cpus);
418 398
419 /* Poke the watchdog to clear out its state */ 399 /* Poke the watchdog to clear out its state */
420 cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1); 400 cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(core), 1);
421 401
422 /* Finally enable the watchdog now that all handlers are installed */ 402 /* Finally enable the watchdog now that all handlers are installed */
423 ciu_wdog.u64 = 0; 403 ciu_wdog.u64 = 0;
424 ciu_wdog.s.len = timeout_cnt; 404 ciu_wdog.s.len = timeout_cnt;
425 ciu_wdog.s.mode = 3; /* 3 = Interrupt + NMI + Soft-Reset */ 405 ciu_wdog.s.mode = 3; /* 3 = Interrupt + NMI + Soft-Reset */
426 cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64); 406 cvmx_write_csr_node(node, CVMX_CIU_WDOGX(core), ciu_wdog.u64);
427 407
428 return 0; 408 return 0;
429} 409}
@@ -432,17 +412,20 @@ static int octeon_wdt_ping(struct watchdog_device __always_unused *wdog)
432{ 412{
433 int cpu; 413 int cpu;
434 int coreid; 414 int coreid;
415 int node;
416
417 if (disable)
418 return 0;
435 419
436 for_each_online_cpu(cpu) { 420 for_each_online_cpu(cpu) {
437 coreid = cpu2core(cpu); 421 coreid = cpu2core(cpu);
438 cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1); 422 node = cpu_to_node(cpu);
423 cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(coreid), 1);
439 per_cpu_countdown[cpu] = countdown_reset; 424 per_cpu_countdown[cpu] = countdown_reset;
440 if ((countdown_reset || !do_coundown) && 425 if ((countdown_reset || !do_countdown) &&
441 !cpumask_test_cpu(cpu, &irq_enabled_cpus)) { 426 !cpumask_test_cpu(cpu, &irq_enabled_cpus)) {
442 /* We have to enable the irq */ 427 /* We have to enable the irq */
443 int irq = OCTEON_IRQ_WDOG0 + coreid; 428 enable_irq(octeon_wdt_cpu_to_irq(cpu));
444
445 enable_irq(irq);
446 cpumask_set_cpu(cpu, &irq_enabled_cpus); 429 cpumask_set_cpu(cpu, &irq_enabled_cpus);
447 } 430 }
448 } 431 }
@@ -472,7 +455,7 @@ static void octeon_wdt_calc_parameters(int t)
472 455
473 countdown_reset = periods > 2 ? periods - 2 : 0; 456 countdown_reset = periods > 2 ? periods - 2 : 0;
474 heartbeat = t; 457 heartbeat = t;
475 timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * timeout_sec) >> 8; 458 timeout_cnt = ((octeon_get_io_clock_rate() / divisor) * timeout_sec) >> 8;
476} 459}
477 460
478static int octeon_wdt_set_timeout(struct watchdog_device *wdog, 461static int octeon_wdt_set_timeout(struct watchdog_device *wdog,
@@ -481,20 +464,25 @@ static int octeon_wdt_set_timeout(struct watchdog_device *wdog,
481 int cpu; 464 int cpu;
482 int coreid; 465 int coreid;
483 union cvmx_ciu_wdogx ciu_wdog; 466 union cvmx_ciu_wdogx ciu_wdog;
467 int node;
484 468
485 if (t <= 0) 469 if (t <= 0)
486 return -1; 470 return -1;
487 471
488 octeon_wdt_calc_parameters(t); 472 octeon_wdt_calc_parameters(t);
489 473
474 if (disable)
475 return 0;
476
490 for_each_online_cpu(cpu) { 477 for_each_online_cpu(cpu) {
491 coreid = cpu2core(cpu); 478 coreid = cpu2core(cpu);
492 cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1); 479 node = cpu_to_node(cpu);
480 cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(coreid), 1);
493 ciu_wdog.u64 = 0; 481 ciu_wdog.u64 = 0;
494 ciu_wdog.s.len = timeout_cnt; 482 ciu_wdog.s.len = timeout_cnt;
495 ciu_wdog.s.mode = 3; /* 3 = Interrupt + NMI + Soft-Reset */ 483 ciu_wdog.s.mode = 3; /* 3 = Interrupt + NMI + Soft-Reset */
496 cvmx_write_csr(CVMX_CIU_WDOGX(coreid), ciu_wdog.u64); 484 cvmx_write_csr_node(node, CVMX_CIU_WDOGX(coreid), ciu_wdog.u64);
497 cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1); 485 cvmx_write_csr_node(node, CVMX_CIU_PP_POKEX(coreid), 1);
498 } 486 }
499 octeon_wdt_ping(wdog); /* Get the irqs back on. */ 487 octeon_wdt_ping(wdog); /* Get the irqs back on. */
500 return 0; 488 return 0;
@@ -503,13 +491,13 @@ static int octeon_wdt_set_timeout(struct watchdog_device *wdog,
503static int octeon_wdt_start(struct watchdog_device *wdog) 491static int octeon_wdt_start(struct watchdog_device *wdog)
504{ 492{
505 octeon_wdt_ping(wdog); 493 octeon_wdt_ping(wdog);
506 do_coundown = 1; 494 do_countdown = 1;
507 return 0; 495 return 0;
508} 496}
509 497
510static int octeon_wdt_stop(struct watchdog_device *wdog) 498static int octeon_wdt_stop(struct watchdog_device *wdog)
511{ 499{
512 do_coundown = 0; 500 do_countdown = 0;
513 octeon_wdt_ping(wdog); 501 octeon_wdt_ping(wdog);
514 return 0; 502 return 0;
515} 503}
@@ -540,14 +528,25 @@ static enum cpuhp_state octeon_wdt_online;
540 */ 528 */
541static int __init octeon_wdt_init(void) 529static int __init octeon_wdt_init(void)
542{ 530{
543 int i;
544 int ret; 531 int ret;
545 u64 *ptr; 532
533 octeon_wdt_bootvector = cvmx_boot_vector_get();
534 if (!octeon_wdt_bootvector) {
535 pr_err("Error: Cannot allocate boot vector.\n");
536 return -ENOMEM;
537 }
538
539 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
540 divisor = 0x200;
541 else if (OCTEON_IS_MODEL(OCTEON_CN78XX))
542 divisor = 0x400;
543 else
544 divisor = 0x100;
546 545
547 /* 546 /*
548 * Watchdog time expiration length = The 16 bits of LEN 547 * Watchdog time expiration length = The 16 bits of LEN
549 * represent the most significant bits of a 24 bit decrementer 548 * represent the most significant bits of a 24 bit decrementer
550 * that decrements every 256 cycles. 549 * that decrements every divisor cycle.
551 * 550 *
552 * Try for a timeout of 5 sec, if that fails a smaller number 551 * Try for a timeout of 5 sec, if that fails a smaller number
553 * of even seconds, 552 * of even seconds,
@@ -555,8 +554,7 @@ static int __init octeon_wdt_init(void)
555 max_timeout_sec = 6; 554 max_timeout_sec = 6;
556 do { 555 do {
557 max_timeout_sec--; 556 max_timeout_sec--;
558 timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * 557 timeout_cnt = ((octeon_get_io_clock_rate() / divisor) * max_timeout_sec) >> 8;
559 max_timeout_sec) >> 8;
560 } while (timeout_cnt > 65535); 558 } while (timeout_cnt > 65535);
561 559
562 BUG_ON(timeout_cnt == 0); 560 BUG_ON(timeout_cnt == 0);
@@ -576,16 +574,10 @@ static int __init octeon_wdt_init(void)
576 return ret; 574 return ret;
577 } 575 }
578 576
579 /* Build the NMI handler ... */ 577 if (disable) {
580 octeon_wdt_build_stage1(); 578 pr_notice("disabled\n");
581 579 return 0;
582 /* ... and install it. */
583 ptr = (u64 *) nmi_stage1_insns;
584 for (i = 0; i < 16; i++) {
585 cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8);
586 cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, ptr[i]);
587 } 580 }
588 cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000);
589 581
590 cpumask_clear(&irq_enabled_cpus); 582 cpumask_clear(&irq_enabled_cpus);
591 583
@@ -607,6 +599,10 @@ err:
607static void __exit octeon_wdt_cleanup(void) 599static void __exit octeon_wdt_cleanup(void)
608{ 600{
609 watchdog_unregister_device(&octeon_wdt); 601 watchdog_unregister_device(&octeon_wdt);
602
603 if (disable)
604 return;
605
610 cpuhp_remove_state(octeon_wdt_online); 606 cpuhp_remove_state(octeon_wdt_online);
611 607
612 /* 608 /*
@@ -617,7 +613,7 @@ static void __exit octeon_wdt_cleanup(void)
617} 613}
618 614
619MODULE_LICENSE("GPL"); 615MODULE_LICENSE("GPL");
620MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); 616MODULE_AUTHOR("Cavium Inc. <support@cavium.com>");
621MODULE_DESCRIPTION("Cavium Networks Octeon Watchdog driver."); 617MODULE_DESCRIPTION("Cavium Inc. OCTEON Watchdog driver.");
622module_init(octeon_wdt_init); 618module_init(octeon_wdt_init);
623module_exit(octeon_wdt_cleanup); 619module_exit(octeon_wdt_cleanup);
diff --git a/drivers/watchdog/octeon-wdt-nmi.S b/drivers/watchdog/octeon-wdt-nmi.S
index 8a900a5e3233..97f6eb7b5a8e 100644
--- a/drivers/watchdog/octeon-wdt-nmi.S
+++ b/drivers/watchdog/octeon-wdt-nmi.S
@@ -3,20 +3,40 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2007 Cavium Networks 6 * Copyright (C) 2007-2017 Cavium, Inc.
7 */ 7 */
8#include <asm/asm.h> 8#include <asm/asm.h>
9#include <asm/regdef.h> 9#include <asm/regdef.h>
10 10
11#define SAVE_REG(r) sd $r, -32768+6912-(32-r)*8($0) 11#define CVMSEG_BASE -32768
12#define CVMSEG_SIZE 6912
13#define SAVE_REG(r) sd $r, CVMSEG_BASE + CVMSEG_SIZE - ((32 - r) * 8)($0)
12 14
13 NESTED(octeon_wdt_nmi_stage2, 0, sp) 15 NESTED(octeon_wdt_nmi_stage2, 0, sp)
14 .set push 16 .set push
15 .set noreorder 17 .set noreorder
16 .set noat 18 .set noat
17 /* Save all registers to the top CVMSEG. This shouldn't 19 /* Clear Dcache so cvmseg works right. */
20 cache 1,0($0)
21 /* Use K0 to do a read/modify/write of CVMMEMCTL */
22 dmfc0 k0, $11, 7
23 /* Clear out the size of CVMSEG */
24 dins k0, $0, 0, 6
25 /* Set CVMSEG to its largest value */
26 ori k0, k0, 0x1c0 | 54
27 /* Store the CVMMEMCTL value */
28 dmtc0 k0, $11, 7
29 /*
30 * Restore K0 from the debug scratch register, it was saved in
31 * the boot-vector code.
32 */
33 dmfc0 k0, $31
34
35 /*
36 * Save all registers to the top CVMSEG. This shouldn't
18 * corrupt any state used by the kernel. Also all registers 37 * corrupt any state used by the kernel. Also all registers
19 * should have the value right before the NMI. */ 38 * should have the value right before the NMI.
39 */
20 SAVE_REG(0) 40 SAVE_REG(0)
21 SAVE_REG(1) 41 SAVE_REG(1)
22 SAVE_REG(2) 42 SAVE_REG(2)
@@ -49,16 +69,22 @@
49 SAVE_REG(29) 69 SAVE_REG(29)
50 SAVE_REG(30) 70 SAVE_REG(30)
51 SAVE_REG(31) 71 SAVE_REG(31)
72 /* Write zero to all CVMSEG locations per Core-15169 */
73 dli a0, CVMSEG_SIZE - (33 * 8)
741: sd zero, CVMSEG_BASE(a0)
75 daddiu a0, a0, -8
76 bgez a0, 1b
77 nop
52 /* Set the stack to begin right below the registers */ 78 /* Set the stack to begin right below the registers */
53 li sp, -32768+6912-32*8 79 dli sp, CVMSEG_BASE + CVMSEG_SIZE - (32 * 8)
54 /* Load the address of the third stage handler */ 80 /* Load the address of the third stage handler */
55 dla a0, octeon_wdt_nmi_stage3 81 dla $25, octeon_wdt_nmi_stage3
56 /* Call the third stage handler */ 82 /* Call the third stage handler */
57 jal a0 83 jal $25
58 /* a0 is the address of the saved registers */ 84 /* a0 is the address of the saved registers */
59 move a0, sp 85 move a0, sp
60 /* Loop forvever if we get here. */ 86 /* Loop forvever if we get here. */
611: b 1b 872: b 2b
62 nop 88 nop
63 .set pop 89 .set pop
64 END(octeon_wdt_nmi_stage2) 90 END(octeon_wdt_nmi_stage2)
diff --git a/include/dt-bindings/mips/lantiq_rcu_gphy.h b/include/dt-bindings/mips/lantiq_rcu_gphy.h
new file mode 100644
index 000000000000..fa1a63773342
--- /dev/null
+++ b/include/dt-bindings/mips/lantiq_rcu_gphy.h
@@ -0,0 +1,15 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
7 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
8 */
9#ifndef _DT_BINDINGS_MIPS_LANTIQ_RCU_GPHY_H
10#define _DT_BINDINGS_MIPS_LANTIQ_RCU_GPHY_H
11
12#define GPHY_MODE_GE 1
13#define GPHY_MODE_FE 2
14
15#endif /* _DT_BINDINGS_MIPS_LANTIQ_RCU_GPHY_H */
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h
deleted file mode 100644
index 2b0e56619e53..000000000000
--- a/include/linux/irqchip/mips-gic.h
+++ /dev/null
@@ -1,297 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2000, 07 MIPS Technologies, Inc.
7 */
8#ifndef __LINUX_IRQCHIP_MIPS_GIC_H
9#define __LINUX_IRQCHIP_MIPS_GIC_H
10
11#include <linux/clocksource.h>
12#include <linux/ioport.h>
13
14#define GIC_MAX_INTRS 256
15
16/* Constants */
17#define GIC_POL_POS 1
18#define GIC_POL_NEG 0
19#define GIC_TRIG_EDGE 1
20#define GIC_TRIG_LEVEL 0
21#define GIC_TRIG_DUAL_ENABLE 1
22#define GIC_TRIG_DUAL_DISABLE 0
23
24#define MSK(n) ((1 << (n)) - 1)
25
26/* Accessors */
27#define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS)
28
29/* GIC Address Space */
30#define SHARED_SECTION_OFS 0x0000
31#define SHARED_SECTION_SIZE 0x8000
32#define VPE_LOCAL_SECTION_OFS 0x8000
33#define VPE_LOCAL_SECTION_SIZE 0x4000
34#define VPE_OTHER_SECTION_OFS 0xc000
35#define VPE_OTHER_SECTION_SIZE 0x4000
36#define USM_VISIBLE_SECTION_OFS 0x10000
37#define USM_VISIBLE_SECTION_SIZE 0x10000
38
39/* Register Map for Shared Section */
40
41#define GIC_SH_CONFIG_OFS 0x0000
42
43/* Shared Global Counter */
44#define GIC_SH_COUNTER_31_00_OFS 0x0010
45/* 64-bit counter register for CM3 */
46#define GIC_SH_COUNTER_OFS GIC_SH_COUNTER_31_00_OFS
47#define GIC_SH_COUNTER_63_32_OFS 0x0014
48#define GIC_SH_REVISIONID_OFS 0x0020
49
50/* Convert an interrupt number to a byte offset/bit for multi-word registers */
51#define GIC_INTR_OFS(intr) ({ \
52 unsigned bits = mips_cm_is64 ? 64 : 32; \
53 unsigned reg_idx = (intr) / bits; \
54 unsigned reg_width = bits / 8; \
55 \
56 reg_idx * reg_width; \
57})
58#define GIC_INTR_BIT(intr) ((intr) % (mips_cm_is64 ? 64 : 32))
59
60/* Polarity : Reset Value is always 0 */
61#define GIC_SH_SET_POLARITY_OFS 0x0100
62
63/* Triggering : Reset Value is always 0 */
64#define GIC_SH_SET_TRIGGER_OFS 0x0180
65
66/* Dual edge triggering : Reset Value is always 0 */
67#define GIC_SH_SET_DUAL_OFS 0x0200
68
69/* Set/Clear corresponding bit in Edge Detect Register */
70#define GIC_SH_WEDGE_OFS 0x0280
71
72/* Mask manipulation */
73#define GIC_SH_RMASK_OFS 0x0300
74#define GIC_SH_SMASK_OFS 0x0380
75
76/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
77#define GIC_SH_MASK_OFS 0x0400
78
79/* Pending Global Interrupts (RO) */
80#define GIC_SH_PEND_OFS 0x0480
81
82/* Maps Interrupt X to a Pin */
83#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
84#define GIC_SH_MAP_TO_PIN(intr) (4 * (intr))
85
86/* Maps Interrupt X to a VPE */
87#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
88#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
89 ((32 * (intr)) + (((vpe) / 32) * 4))
90#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))
91
92/* Register Map for Local Section */
93#define GIC_VPE_CTL_OFS 0x0000
94#define GIC_VPE_PEND_OFS 0x0004
95#define GIC_VPE_MASK_OFS 0x0008
96#define GIC_VPE_RMASK_OFS 0x000c
97#define GIC_VPE_SMASK_OFS 0x0010
98#define GIC_VPE_WD_MAP_OFS 0x0040
99#define GIC_VPE_COMPARE_MAP_OFS 0x0044
100#define GIC_VPE_TIMER_MAP_OFS 0x0048
101#define GIC_VPE_FDC_MAP_OFS 0x004c
102#define GIC_VPE_PERFCTR_MAP_OFS 0x0050
103#define GIC_VPE_SWINT0_MAP_OFS 0x0054
104#define GIC_VPE_SWINT1_MAP_OFS 0x0058
105#define GIC_VPE_OTHER_ADDR_OFS 0x0080
106#define GIC_VP_IDENT_OFS 0x0088
107#define GIC_VPE_WD_CONFIG0_OFS 0x0090
108#define GIC_VPE_WD_COUNT0_OFS 0x0094
109#define GIC_VPE_WD_INITIAL0_OFS 0x0098
110#define GIC_VPE_COMPARE_LO_OFS 0x00a0
111/* 64-bit Compare register on CM3 */
112#define GIC_VPE_COMPARE_OFS GIC_VPE_COMPARE_LO_OFS
113#define GIC_VPE_COMPARE_HI_OFS 0x00a4
114
115#define GIC_VPE_EIC_SHADOW_SET_BASE_OFS 0x0100
116#define GIC_VPE_EIC_SS(intr) (4 * (intr))
117
118#define GIC_VPE_EIC_VEC_BASE_OFS 0x0800
119#define GIC_VPE_EIC_VEC(intr) (4 * (intr))
120
121#define GIC_VPE_TENABLE_NMI_OFS 0x1000
122#define GIC_VPE_TENABLE_YQ_OFS 0x1004
123#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080
124#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084
125
126/* User Mode Visible Section Register Map */
127#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000
128#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004
129
130/* Masks */
131#define GIC_SH_CONFIG_COUNTSTOP_SHF 28
132#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
133
134#define GIC_SH_CONFIG_COUNTBITS_SHF 24
135#define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF)
136
137#define GIC_SH_CONFIG_NUMINTRS_SHF 16
138#define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
139
140#define GIC_SH_CONFIG_NUMVPES_SHF 0
141#define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF)
142
143#define GIC_SH_WEDGE_SET(intr) ((intr) | (0x1 << 31))
144#define GIC_SH_WEDGE_CLR(intr) ((intr) & ~(0x1 << 31))
145
146#define GIC_MAP_TO_PIN_SHF 31
147#define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF)
148#define GIC_MAP_TO_NMI_SHF 30
149#define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF)
150#define GIC_MAP_TO_YQ_SHF 29
151#define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF)
152#define GIC_MAP_SHF 0
153#define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF)
154
155/* GIC_VPE_CTL Masks */
156#define GIC_VPE_CTL_FDC_RTBL_SHF 4
157#define GIC_VPE_CTL_FDC_RTBL_MSK (MSK(1) << GIC_VPE_CTL_FDC_RTBL_SHF)
158#define GIC_VPE_CTL_SWINT_RTBL_SHF 3
159#define GIC_VPE_CTL_SWINT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_SWINT_RTBL_SHF)
160#define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2
161#define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF)
162#define GIC_VPE_CTL_TIMER_RTBL_SHF 1
163#define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF)
164#define GIC_VPE_CTL_EIC_MODE_SHF 0
165#define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF)
166
167/* GIC_VPE_PEND Masks */
168#define GIC_VPE_PEND_WD_SHF 0
169#define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF)
170#define GIC_VPE_PEND_CMP_SHF 1
171#define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF)
172#define GIC_VPE_PEND_TIMER_SHF 2
173#define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF)
174#define GIC_VPE_PEND_PERFCOUNT_SHF 3
175#define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF)
176#define GIC_VPE_PEND_SWINT0_SHF 4
177#define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF)
178#define GIC_VPE_PEND_SWINT1_SHF 5
179#define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF)
180#define GIC_VPE_PEND_FDC_SHF 6
181#define GIC_VPE_PEND_FDC_MSK (MSK(1) << GIC_VPE_PEND_FDC_SHF)
182
183/* GIC_VPE_RMASK Masks */
184#define GIC_VPE_RMASK_WD_SHF 0
185#define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF)
186#define GIC_VPE_RMASK_CMP_SHF 1
187#define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF)
188#define GIC_VPE_RMASK_TIMER_SHF 2
189#define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF)
190#define GIC_VPE_RMASK_PERFCNT_SHF 3
191#define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF)
192#define GIC_VPE_RMASK_SWINT0_SHF 4
193#define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF)
194#define GIC_VPE_RMASK_SWINT1_SHF 5
195#define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF)
196#define GIC_VPE_RMASK_FDC_SHF 6
197#define GIC_VPE_RMASK_FDC_MSK (MSK(1) << GIC_VPE_RMASK_FDC_SHF)
198
199/* GIC_VPE_SMASK Masks */
200#define GIC_VPE_SMASK_WD_SHF 0
201#define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF)
202#define GIC_VPE_SMASK_CMP_SHF 1
203#define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF)
204#define GIC_VPE_SMASK_TIMER_SHF 2
205#define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF)
206#define GIC_VPE_SMASK_PERFCNT_SHF 3
207#define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF)
208#define GIC_VPE_SMASK_SWINT0_SHF 4
209#define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF)
210#define GIC_VPE_SMASK_SWINT1_SHF 5
211#define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF)
212#define GIC_VPE_SMASK_FDC_SHF 6
213#define GIC_VPE_SMASK_FDC_MSK (MSK(1) << GIC_VPE_SMASK_FDC_SHF)
214
215/* GIC_VP_IDENT fields */
216#define GIC_VP_IDENT_VCNUM_SHF 0
217#define GIC_VP_IDENT_VCNUM_MSK (MSK(6) << GIC_VP_IDENT_VCNUM_SHF)
218
219/* GIC nomenclature for Core Interrupt Pins. */
220#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
221#define GIC_CPU_INT1 1 /* . */
222#define GIC_CPU_INT2 2 /* . */
223#define GIC_CPU_INT3 3 /* . */
224#define GIC_CPU_INT4 4 /* . */
225#define GIC_CPU_INT5 5 /* Core Interrupt 7 */
226
227/* Add 2 to convert GIC CPU pin to core interrupt */
228#define GIC_CPU_PIN_OFFSET 2
229
230/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */
231#define GIC_CPU_TO_VEC_OFFSET 2
232
233/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
234#define GIC_PIN_TO_VEC_OFFSET 1
235
236/* Local GIC interrupts. */
237#define GIC_LOCAL_INT_WD 0 /* GIC watchdog */
238#define GIC_LOCAL_INT_COMPARE 1 /* GIC count and compare timer */
239#define GIC_LOCAL_INT_TIMER 2 /* CPU timer interrupt */
240#define GIC_LOCAL_INT_PERFCTR 3 /* CPU performance counter */
241#define GIC_LOCAL_INT_SWINT0 4 /* CPU software interrupt 0 */
242#define GIC_LOCAL_INT_SWINT1 5 /* CPU software interrupt 1 */
243#define GIC_LOCAL_INT_FDC 6 /* CPU fast debug channel */
244#define GIC_NUM_LOCAL_INTRS 7
245
246/* Convert between local/shared IRQ number and GIC HW IRQ number. */
247#define GIC_LOCAL_HWIRQ_BASE 0
248#define GIC_LOCAL_TO_HWIRQ(x) (GIC_LOCAL_HWIRQ_BASE + (x))
249#define GIC_HWIRQ_TO_LOCAL(x) ((x) - GIC_LOCAL_HWIRQ_BASE)
250#define GIC_SHARED_HWIRQ_BASE GIC_NUM_LOCAL_INTRS
251#define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x))
252#define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE)
253
254#ifdef CONFIG_MIPS_GIC
255
256extern unsigned int gic_present;
257
258extern void gic_init(unsigned long gic_base_addr,
259 unsigned long gic_addrspace_size, unsigned int cpu_vec,
260 unsigned int irqbase);
261extern u64 gic_read_count(void);
262extern unsigned int gic_get_count_width(void);
263extern u64 gic_read_compare(void);
264extern void gic_write_compare(u64 cnt);
265extern void gic_write_cpu_compare(u64 cnt, int cpu);
266extern void gic_start_count(void);
267extern void gic_stop_count(void);
268extern int gic_get_c0_compare_int(void);
269extern int gic_get_c0_perfcount_int(void);
270extern int gic_get_c0_fdc_int(void);
271extern int gic_get_usm_range(struct resource *gic_usm_res);
272
273#else /* CONFIG_MIPS_GIC */
274
275#define gic_present 0
276
277static inline int gic_get_usm_range(struct resource *gic_usm_res)
278{
279 /* Shouldn't be called. */
280 return -1;
281}
282
283#endif /* CONFIG_MIPS_GIC */
284
285/**
286 * gic_read_local_vp_id() - read the local VPs VCNUM
287 *
288 * Read the VCNUM of the local VP from the GIC_VP_IDENT register and
289 * return it to the caller. This ID should be used to refer to the VP
290 * via the GICs VP-other region, or when calculating an offset to a
291 * bit representing the VP in interrupt masks.
292 *
293 * Return: The VCNUM value for the local VP.
294 */
295extern unsigned gic_read_local_vp_id(void);
296
297#endif /* __LINUX_IRQCHIP_MIPS_GIC_H */