diff options
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 @@ | |||
1 | Lantiq XWAY SoC FPI BUS binding | ||
2 | ============================ | ||
3 | |||
4 | |||
5 | ------------------------------------------------------------------------------- | ||
6 | Required 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 | ------------------------------------------------------------------------------- | ||
17 | Example 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 @@ | |||
1 | Lantiq XWAY SoC GPHY binding | ||
2 | ============================ | ||
3 | |||
4 | This binding describes a software-defined ethernet PHY, provided by the RCU | ||
5 | module on newer Lantiq XWAY SoCs (xRX200 and newer). | ||
6 | |||
7 | ------------------------------------------------------------------------------- | ||
8 | Required 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 | |||
19 | Optional 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 | ------------------------------------------------------------------------------- | ||
25 | Example 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 @@ | |||
1 | Lantiq XWAY SoC RCU binding | ||
2 | =========================== | ||
3 | |||
4 | This binding describes the RCU (reset controller unit) multifunction device, | ||
5 | where each sub-device has it's own set of registers. | ||
6 | |||
7 | The RCU register range is used for multiple purposes. Mostly one device | ||
8 | uses one or multiple register exclusively, but for some registers some | ||
9 | bits are for one driver and some other bits are for a different driver. | ||
10 | With this patch all accesses to the RCU registers will go through | ||
11 | syscon. | ||
12 | |||
13 | |||
14 | ------------------------------------------------------------------------------- | ||
15 | Required 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 | ------------------------------------------------------------------------------- | ||
22 | Example 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 @@ | |||
1 | National Instruments MIPS platforms | ||
2 | |||
3 | required root node properties: | ||
4 | - compatible: must be "ni,169445" | ||
5 | |||
6 | CPU 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 @@ | |||
1 | Lantiq XWAY SoC RCU USB 1.1/2.0 PHY binding | ||
2 | =========================================== | ||
3 | |||
4 | This binding describes the USB PHY hardware provided by the RCU module on the | ||
5 | Lantiq XWAY SoCs. | ||
6 | |||
7 | This node has to be a sub node of the Lantiq RCU block. | ||
8 | |||
9 | ------------------------------------------------------------------------------- | ||
10 | Required 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 | ------------------------------------------------------------------------------- | ||
30 | Example 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 @@ | |||
1 | Lantiq XWAY SoC RCU reset controller binding | ||
2 | ============================================ | ||
3 | |||
4 | This binding describes a reset-controller found on the RCU module on Lantiq | ||
5 | XWAY SoCs. | ||
6 | |||
7 | This node has to be a sub node of the Lantiq RCU block. | ||
8 | |||
9 | ------------------------------------------------------------------------------- | ||
10 | Required 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 | ------------------------------------------------------------------------------- | ||
24 | Example 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. | |||
361 | via VIA Technologies, Inc. | 361 | via VIA Technologies, Inc. |
362 | virtio Virtual I/O Device Specification, developed by the OASIS consortium | 362 | virtio Virtual I/O Device Specification, developed by the OASIS consortium |
363 | vivante Vivante Corporation | 363 | vivante Vivante Corporation |
364 | vocore VoCore Studio | ||
364 | voipac Voipac Technologies s.r.o. | 365 | voipac Voipac Technologies s.r.o. |
365 | wd Western Digital Corp. | 366 | wd Western Digital Corp. |
366 | wetek WeTek Electronics, limited. | 367 | wetek 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 @@ | |||
1 | Lantiq WTD watchdog binding | ||
2 | ============================ | ||
3 | |||
4 | This describes the binding of the Lantiq watchdog driver. | ||
5 | |||
6 | ------------------------------------------------------------------------------- | ||
7 | Required 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 | ------------------------------------------------------------------------------- | ||
18 | Example 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> | |||
7717 | L: linux-mips@linux-mips.org | 7717 | L: linux-mips@linux-mips.org |
7718 | S: Maintained | 7718 | S: Maintained |
7719 | F: arch/mips/lantiq | 7719 | F: arch/mips/lantiq |
7720 | F: drivers/soc/lantiq | ||
7720 | 7721 | ||
7721 | LAPB module | 7722 | LAPB module |
7722 | L: linux-x25@vger.kernel.org | 7723 | L: linux-x25@vger.kernel.org |
@@ -8982,6 +8983,7 @@ M: Paul Burton <paul.burton@imgtec.com> | |||
8982 | L: linux-mips@linux-mips.org | 8983 | L: linux-mips@linux-mips.org |
8983 | S: Supported | 8984 | S: Supported |
8984 | F: arch/mips/generic/ | 8985 | F: arch/mips/generic/ |
8986 | F: arch/mips/tools/generic-board-config.sh | ||
8985 | 8987 | ||
8986 | MIPS/LOONGSON1 ARCHITECTURE | 8988 | MIPS/LOONGSON1 ARCHITECTURE |
8987 | M: Keguang Zhang <keguang.zhang@gmail.com> | 8989 | M: Keguang Zhang <keguang.zhang@gmail.com> |
@@ -8992,6 +8994,13 @@ F: arch/mips/include/asm/mach-loongson32/ | |||
8992 | F: drivers/*/*loongson1* | 8994 | F: drivers/*/*loongson1* |
8993 | F: drivers/*/*/*loongson1* | 8995 | F: drivers/*/*/*loongson1* |
8994 | 8996 | ||
8997 | MIPS RINT INSTRUCTION EMULATION | ||
8998 | M: Aleksandar Markovic <aleksandar.markovic@imgtec.com> | ||
8999 | L: linux-mips@linux-mips.org | ||
9000 | S: Supported | ||
9001 | F: arch/mips/math-emu/sp_rint.c | ||
9002 | F: arch/mips/math-emu/dp_rint.c | ||
9003 | |||
8995 | MIROSOUND PCM20 FM RADIO RECEIVER DRIVER | 9004 | MIROSOUND PCM20 FM RADIO RECEIVER DRIVER |
8996 | M: Hans Verkuil <hverkuil@xs4all.nl> | 9005 | M: Hans Verkuil <hverkuil@xs4all.nl> |
8997 | L: linux-media@vger.kernel.org | 9006 | L: linux-media@vger.kernel.org |
@@ -9869,6 +9878,12 @@ F: drivers/regulator/twl-regulator.c | |||
9869 | F: drivers/regulator/twl6030-regulator.c | 9878 | F: drivers/regulator/twl6030-regulator.c |
9870 | F: include/linux/i2c-omap.h | 9879 | F: include/linux/i2c-omap.h |
9871 | 9880 | ||
9881 | ONION OMEGA2+ BOARD | ||
9882 | M: Harvey Hunt <harveyhuntnexus@gmail.com> | ||
9883 | L: linux-mips@linux-mips.org | ||
9884 | S: Maintained | ||
9885 | F: arch/mips/boot/dts/ralink/omega2p.dts | ||
9886 | |||
9872 | OMFS FILESYSTEM | 9887 | OMFS FILESYSTEM |
9873 | M: Bob Copeland <me@bobcopeland.com> | 9888 | M: Bob Copeland <me@bobcopeland.com> |
9874 | L: linux-karma-devel@lists.sourceforge.net | 9889 | L: linux-karma-devel@lists.sourceforge.net |
@@ -14390,6 +14405,12 @@ L: netdev@vger.kernel.org | |||
14390 | S: Maintained | 14405 | S: Maintained |
14391 | F: drivers/net/vmxnet3/ | 14406 | F: drivers/net/vmxnet3/ |
14392 | 14407 | ||
14408 | VOCORE VOCORE2 BOARD | ||
14409 | M: Harvey Hunt <harveyhuntnexus@gmail.com> | ||
14410 | L: linux-mips@linux-mips.org | ||
14411 | S: Maintained | ||
14412 | F: arch/mips/boot/dts/ralink/vocore2.dts | ||
14413 | |||
14393 | VOLTAGE AND CURRENT REGULATOR FRAMEWORK | 14414 | VOLTAGE AND CURRENT REGULATOR FRAMEWORK |
14394 | M: Liam Girdwood <lgirdwood@gmail.com> | 14415 | M: Liam Girdwood <lgirdwood@gmail.com> |
14395 | M: Mark Brown <broonie@kernel.org> | 14416 | M: 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 | ||
1630 | config 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 | |||
1638 | config CPU_NEVADA | 1630 | config 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 | |||
1950 | config SYS_HAS_CPU_R5500 | 1942 | config SYS_HAS_CPU_R5500 |
1951 | bool | 1943 | bool |
1952 | 1944 | ||
1953 | config SYS_HAS_CPU_R6000 | ||
1954 | bool | ||
1955 | |||
1956 | config SYS_HAS_CPU_NEVADA | 1945 | config SYS_HAS_CPU_NEVADA |
1957 | bool | 1946 | bool |
1958 | 1947 | ||
@@ -2180,7 +2169,7 @@ config PAGE_SIZE_32KB | |||
2180 | 2169 | ||
2181 | config PAGE_SIZE_64KB | 2170 | config 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 | ||
2249 | config CPU_GENERIC_DUMP_TLB | 2238 | config 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 | ||
2253 | config CPU_R4K_FPU | 2242 | config 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 | ||
2257 | config CPU_R4K_CACHE_TLB | 2246 | config CPU_R4K_CACHE_TLB |
2258 | bool | 2247 | bool |
@@ -2260,6 +2249,7 @@ config CPU_R4K_CACHE_TLB | |||
2260 | 2249 | ||
2261 | config MIPS_MT_SMP | 2250 | config 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 | ||
2394 | config MIPS_CPS_PM | 2383 | config MIPS_CPS_PM |
2395 | depends on MIPS_CPS | 2384 | depends on MIPS_CPS |
2396 | select MIPS_CPC | ||
2397 | bool | 2385 | bool |
2398 | 2386 | ||
2399 | config MIPS_CM | 2387 | config MIPS_CM |
2400 | bool | 2388 | bool |
2389 | select MIPS_CPC | ||
2401 | 2390 | ||
2402 | config MIPS_CPC | 2391 | config 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 | # |
152 | cflags-$(CONFIG_CPU_R3000) += -march=r3000 | 152 | cflags-$(CONFIG_CPU_R3000) += -march=r3000 |
153 | cflags-$(CONFIG_CPU_TX39XX) += -march=r3900 | 153 | cflags-$(CONFIG_CPU_TX39XX) += -march=r3900 |
154 | cflags-$(CONFIG_CPU_R6000) += -march=r6000 -Wa,--trap | ||
155 | cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap | 154 | cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap |
156 | cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap | 155 | cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap |
157 | cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap | 156 | cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap |
@@ -291,7 +290,8 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) | |||
291 | 290 | ||
292 | bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ | 291 | bootvars-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)" | ||
295 | ifdef CONFIG_32BIT | 295 | ifdef CONFIG_32BIT |
296 | bootvars-y += ADDR_BITS=32 | 296 | bootvars-y += ADDR_BITS=32 |
297 | endif | 297 | endif |
@@ -299,6 +299,10 @@ ifdef CONFIG_64BIT | |||
299 | bootvars-y += ADDR_BITS=64 | 299 | bootvars-y += ADDR_BITS=64 |
300 | endif | 300 | endif |
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. | ||
304 | KBUILD_CFLAGS += -fno-asynchronous-unwind-tables | ||
305 | |||
302 | LDFLAGS += -m $(ld-emul) | 306 | LDFLAGS += -m $(ld-emul) |
303 | 307 | ||
304 | ifdef CONFIG_MIPS | 308 | ifdef 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 | ||
527 | generic_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 | */ |
350 | static irqreturn_t db1200_mmc_cd(int irq, void *ptr) | 350 | static 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) { | 356 | static 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 | ||
437 | static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr) | 441 | static 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) { | 447 | static 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 | ||
451 | static irqreturn_t db1300_mmc_cd(int irq, void *ptr) | 451 | static 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 */ | 457 | static 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 | ||
98 | static int __init db1xxx_dev_init(void) | 99 | static 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 | ||
431 | unsigned long clk_get_rate(struct clk *clk) | 431 | unsigned 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 | } |
435 | EXPORT_SYMBOL(clk_get_rate); | 438 | EXPORT_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 | ||
340 | unsigned long clk_get_rate(struct clk *clk) | 340 | unsigned 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 |
119 | endif | 119 | endif |
120 | 120 | ||
121 | quiet_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 | |||
121 | quiet_cmd_cpp_its_S = ITS $@ | 127 | quiet_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 | ||
146 | quiet_cmd_itb-image = ITB $@ | 152 | quiet_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 | |||
5 | dts-dirs += lantiq | 5 | dts-dirs += lantiq |
6 | dts-dirs += mti | 6 | dts-dirs += mti |
7 | dts-dirs += netlogic | 7 | dts-dirs += netlogic |
8 | dts-dirs += ni | ||
8 | dts-dirs += pic32 | 9 | dts-dirs += pic32 |
9 | dts-dirs += qca | 10 | dts-dirs += qca |
10 | dts-dirs += ralink | 11 | dts-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 = <ð0_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 @@ | |||
1 | dtb-$(CONFIG_FIT_IMAGE_FDT_NI169445) += 169445.dtb | ||
2 | |||
3 | # Force kbuild to make empty built-in.o if necessary | ||
4 | obj- += dummy.o | ||
5 | |||
6 | always := $(dtb-y) | ||
7 | clean-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 | |||
2 | dtb-$(CONFIG_DTB_RT305X_EVAL) += rt3052_eval.dtb | 2 | dtb-$(CONFIG_DTB_RT305X_EVAL) += rt3052_eval.dtb |
3 | dtb-$(CONFIG_DTB_RT3883_EVAL) += rt3883_eval.dtb | 3 | dtb-$(CONFIG_DTB_RT3883_EVAL) += rt3883_eval.dtb |
4 | dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb | 4 | dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb |
5 | dtb-$(CONFIG_DTB_OMEGA2P) += omega2p.dtb | ||
6 | dtb-$(CONFIG_DTB_VOCORE2) += vocore2.dtb | ||
5 | 7 | ||
6 | obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) | 8 | obj-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 | ||
19 | obj-y += cvmx-helper-errata.o cvmx-helper-jtag.o | 19 | obj-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 | ||
16 | reset_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 | |||
53 | wait_loop: | ||
54 | wait | ||
55 | nop | ||
56 | |||
57 | b wait_loop | ||
58 | nop | ||
59 | |||
60 | nop | ||
61 | nop | ||
62 | ------------------------------------ | ||
63 | |||
64 | 0000000000000000 <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 | |||
98 | 0000000000000058 <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 | |||
112 | static 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 | |||
134 | static 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 | */ | ||
159 | struct 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 | } | ||
167 | EXPORT_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 | */ | ||
82 | static 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 | ||
150 | void *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 | } | ||
184 | EXPORT_SYMBOL(cvmx_bootmem_alloc_named_range_once); | ||
185 | |||
101 | void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, | 186 | void *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 | |||
2967 | struct 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 | } | ||
2974 | EXPORT_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 | */ |
208 | static void octeon_boot_secondary(int cpu, struct task_struct *idle) | 208 | static 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 | ||
411 | struct plat_smp_ops octeon_smp_ops = { | 415 | const 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 | ||
488 | static struct plat_smp_ops octeon_78xx_smp_ops = { | 492 | static 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 | ||
502 | void __init octeon_setup_smp(void) | 506 | void __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 | |||
60 | CONFIG_ATA=y | 60 | CONFIG_ATA=y |
61 | CONFIG_SATA_AHCI=y | 61 | CONFIG_SATA_AHCI=y |
62 | CONFIG_SATA_AHCI_PLATFORM=y | 62 | CONFIG_SATA_AHCI_PLATFORM=y |
63 | CONFIG_AHCI_OCTEON=y | ||
64 | CONFIG_PATA_OCTEON_CF=y | 63 | CONFIG_PATA_OCTEON_CF=y |
65 | CONFIG_SATA_SIL=y | ||
66 | CONFIG_NETDEVICES=y | 64 | CONFIG_NETDEVICES=y |
67 | CONFIG_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 | |||
121 | CONFIG_SPI_OCTEON=y | 118 | CONFIG_SPI_OCTEON=y |
122 | # CONFIG_HWMON is not set | 119 | # CONFIG_HWMON is not set |
123 | CONFIG_WATCHDOG=y | 120 | CONFIG_WATCHDOG=y |
124 | CONFIG_USB=m | 121 | CONFIG_USB=y |
125 | CONFIG_USB_EHCI_HCD=m | 122 | # CONFIG_USB_PCI is not set |
126 | CONFIG_USB_EHCI_HCD_PLATFORM=m | 123 | CONFIG_USB_XHCI_HCD=y |
127 | CONFIG_USB_OHCI_HCD=m | 124 | CONFIG_USB_EHCI_HCD=y |
128 | CONFIG_USB_OHCI_HCD_PLATFORM=m | 125 | CONFIG_USB_EHCI_HCD_PLATFORM=y |
126 | CONFIG_USB_OHCI_HCD=y | ||
127 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
128 | CONFIG_USB_STORAGE=y | ||
129 | CONFIG_USB_DWC3=y | ||
129 | CONFIG_MMC=y | 130 | CONFIG_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 | ||
133 | CONFIG_MMC_CAVIUM_OCTEON=y | 133 | CONFIG_MMC_CAVIUM_OCTEON=y |
134 | CONFIG_EDAC=y | ||
135 | CONFIG_EDAC_OCTEON_PC=y | ||
136 | CONFIG_EDAC_OCTEON_L2C=y | ||
137 | CONFIG_EDAC_OCTEON_LMC=y | ||
138 | CONFIG_EDAC_OCTEON_PCI=y | ||
134 | CONFIG_RTC_CLASS=y | 139 | CONFIG_RTC_CLASS=y |
135 | CONFIG_RTC_DRV_DS1307=y | 140 | CONFIG_RTC_DRV_DS1307=y |
136 | CONFIG_STAGING=y | 141 | CONFIG_STAGING=y |
137 | CONFIG_OCTEON_ETHERNET=y | 142 | CONFIG_OCTEON_ETHERNET=y |
138 | CONFIG_OCTEON_USB=m | ||
139 | # CONFIG_IOMMU_SUPPORT is not set | 143 | # CONFIG_IOMMU_SUPPORT is not set |
144 | CONFIG_RAS=y | ||
140 | CONFIG_EXT4_FS=y | 145 | CONFIG_EXT4_FS=y |
141 | CONFIG_EXT4_FS_POSIX_ACL=y | 146 | CONFIG_EXT4_FS_POSIX_ACL=y |
142 | CONFIG_EXT4_FS_SECURITY=y | 147 | CONFIG_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 | |||
91 | CONFIG_I2C=y | 91 | CONFIG_I2C=y |
92 | CONFIG_I2C_JZ4780=y | 92 | CONFIG_I2C_JZ4780=y |
93 | CONFIG_GPIO_SYSFS=y | 93 | CONFIG_GPIO_SYSFS=y |
94 | CONFIG_GPIO_INGENIC=y | ||
94 | # CONFIG_HWMON is not set | 95 | # CONFIG_HWMON is not set |
95 | CONFIG_REGULATOR=y | 96 | CONFIG_REGULATOR=y |
96 | CONFIG_REGULATOR_DEBUG=y | 97 | CONFIG_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 |
101 | CONFIG_MMC=y | 102 | CONFIG_MMC=y |
103 | CONFIG_RTC_CLASS=y | ||
104 | CONFIG_RTC_DRV_JZ4740=y | ||
102 | # CONFIG_IOMMU_SUPPORT is not set | 105 | # CONFIG_IOMMU_SUPPORT is not set |
103 | CONFIG_MEMORY=y | 106 | CONFIG_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 | |||
4 | CONFIG_FIT_IMAGE_FDT_NI169445=y | ||
5 | |||
6 | CONFIG_SERIAL_8250=y | ||
7 | CONFIG_SERIAL_8250_CONSOLE=y | ||
8 | CONFIG_SERIAL_OF_PLATFORM=y | ||
9 | |||
10 | CONFIG_GPIOLIB=y | ||
11 | CONFIG_GPIO_SYSFS=y | ||
12 | CONFIG_GPIO_GENERIC_PLATFORM=y | ||
13 | |||
14 | CONFIG_MTD=y | ||
15 | CONFIG_MTD_BLOCK=y | ||
16 | CONFIG_MTD_CMDLINE_PARTS=y | ||
17 | |||
18 | CONFIG_MTD_NAND_ECC=y | ||
19 | CONFIG_MTD_NAND_ECC_BCH=y | ||
20 | CONFIG_MTD_NAND=y | ||
21 | CONFIG_MTD_NAND_GPIO=y | ||
22 | CONFIG_MTD_NAND_IDS=y | ||
23 | |||
24 | CONFIG_MTD_UBI=y | ||
25 | CONFIG_MTD_UBI_BLOCK=y | ||
26 | |||
27 | CONFIG_NETDEVICES=y | ||
28 | CONFIG_STMMAC_ETH=y | ||
29 | CONFIG_STMMAC_PLATFORM=y | ||
30 | CONFIG_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 | |||
1 | CONFIG_LEGACY_BOARD_SEAD3=y | 3 | CONFIG_LEGACY_BOARD_SEAD3=y |
2 | 4 | ||
3 | CONFIG_AUXDISPLAY=y | 5 | CONFIG_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 | |||
3 | CONFIG_MIPS_CPS=y | 3 | CONFIG_MIPS_CPS=y |
4 | CONFIG_CPU_HAS_MSA=y | 4 | CONFIG_CPU_HAS_MSA=y |
5 | CONFIG_HIGHMEM=y | 5 | CONFIG_HIGHMEM=y |
6 | CONFIG_NR_CPUS=2 | 6 | CONFIG_NR_CPUS=16 |
7 | CONFIG_MIPS_O32_FP64_SUPPORT=y | 7 | CONFIG_MIPS_O32_FP64_SUPPORT=y |
8 | CONFIG_SYSVIPC=y | 8 | CONFIG_SYSVIPC=y |
9 | CONFIG_NO_HZ_IDLE=y | 9 | CONFIG_NO_HZ_IDLE=y |
@@ -61,7 +61,6 @@ CONFIG_HID_KENSINGTON=y | |||
61 | CONFIG_HID_LOGITECH=y | 61 | CONFIG_HID_LOGITECH=y |
62 | CONFIG_HID_MICROSOFT=y | 62 | CONFIG_HID_MICROSOFT=y |
63 | CONFIG_HID_MONTEREY=y | 63 | CONFIG_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 |
67 | CONFIG_EXT4_FS=y | 66 | CONFIG_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 | |||
111 | CONFIG_DEV_APPLETALK=m | 111 | CONFIG_DEV_APPLETALK=m |
112 | CONFIG_IPDDP=m | 112 | CONFIG_IPDDP=m |
113 | CONFIG_IPDDP_ENCAP=y | 113 | CONFIG_IPDDP_ENCAP=y |
114 | CONFIG_IPDDP_DECAP=y | ||
115 | CONFIG_X25=m | 114 | CONFIG_X25=m |
116 | CONFIG_LAPB=m | 115 | CONFIG_LAPB=m |
117 | CONFIG_ECONET=m | ||
118 | CONFIG_ECONET_AUNUDP=y | ||
119 | CONFIG_ECONET_NATIVE=y | ||
120 | CONFIG_WAN_ROUTER=m | 116 | CONFIG_WAN_ROUTER=m |
121 | CONFIG_NET_SCHED=y | 117 | CONFIG_NET_SCHED=y |
122 | CONFIG_NET_SCH_CBQ=m | 118 | CONFIG_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 | |||
37 | CONFIG_HIBERNATION=y | 37 | CONFIG_HIBERNATION=y |
38 | CONFIG_PM_STD_PARTITION="/dev/hda3" | 38 | CONFIG_PM_STD_PARTITION="/dev/hda3" |
39 | CONFIG_CPU_FREQ=y | 39 | CONFIG_CPU_FREQ=y |
40 | CONFIG_CPU_FREQ_DEBUG=y | ||
41 | CONFIG_CPU_FREQ_STAT=y | 40 | CONFIG_CPU_FREQ_STAT=y |
42 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 41 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
43 | CONFIG_CPU_FREQ_GOV_POWERSAVE=m | 42 | CONFIG_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 | |||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | 2 | CONFIG_CPU_LITTLE_ENDIAN=y |
3 | CONFIG_CPU_MIPS32_R2=y | 3 | CONFIG_CPU_MIPS32_R2=y |
4 | CONFIG_PAGE_SIZE_16KB=y | 4 | CONFIG_PAGE_SIZE_16KB=y |
5 | CONFIG_MIPS_MT_SMP=y | ||
6 | CONFIG_NR_CPUS=8 | 5 | CONFIG_NR_CPUS=8 |
7 | CONFIG_HZ_100=y | 6 | CONFIG_HZ_100=y |
8 | CONFIG_SYSVIPC=y | 7 | CONFIG_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 | |||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | 2 | CONFIG_CPU_LITTLE_ENDIAN=y |
3 | CONFIG_CPU_MIPS32_R2=y | 3 | CONFIG_CPU_MIPS32_R2=y |
4 | CONFIG_PAGE_SIZE_16KB=y | 4 | CONFIG_PAGE_SIZE_16KB=y |
5 | CONFIG_MIPS_MT_SMP=y | ||
6 | CONFIG_NR_CPUS=8 | 5 | CONFIG_NR_CPUS=8 |
7 | CONFIG_HZ_100=y | 6 | CONFIG_HZ_100=y |
8 | CONFIG_SYSVIPC=y | 7 | CONFIG_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 | |||
3 | CONFIG_CPU_MIPS32_R2=y | 3 | CONFIG_CPU_MIPS32_R2=y |
4 | CONFIG_KVM_GUEST=y | 4 | CONFIG_KVM_GUEST=y |
5 | CONFIG_PAGE_SIZE_16KB=y | 5 | CONFIG_PAGE_SIZE_16KB=y |
6 | # CONFIG_MIPS_MT_SMP is not set | ||
6 | CONFIG_HZ_100=y | 7 | CONFIG_HZ_100=y |
7 | CONFIG_SYSVIPC=y | 8 | CONFIG_SYSVIPC=y |
8 | CONFIG_NO_HZ=y | 9 | CONFIG_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 | |||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | 2 | CONFIG_CPU_LITTLE_ENDIAN=y |
3 | CONFIG_CPU_MIPS32_R2=y | 3 | CONFIG_CPU_MIPS32_R2=y |
4 | CONFIG_PAGE_SIZE_16KB=y | 4 | CONFIG_PAGE_SIZE_16KB=y |
5 | CONFIG_MIPS_MT_SMP=y | ||
6 | CONFIG_SCHED_SMT=y | 5 | CONFIG_SCHED_SMT=y |
7 | CONFIG_MIPS_CPS=y | 6 | CONFIG_MIPS_CPS=y |
8 | CONFIG_NR_CPUS=8 | 7 | CONFIG_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 | |||
3 | CONFIG_CPU_MIPS32_R2=y | 3 | CONFIG_CPU_MIPS32_R2=y |
4 | CONFIG_CPU_MIPS32_3_5_FEATURES=y | 4 | CONFIG_CPU_MIPS32_3_5_FEATURES=y |
5 | CONFIG_PAGE_SIZE_16KB=y | 5 | CONFIG_PAGE_SIZE_16KB=y |
6 | CONFIG_MIPS_MT_SMP=y | ||
7 | CONFIG_SCHED_SMT=y | 6 | CONFIG_SCHED_SMT=y |
8 | CONFIG_MIPS_CPS=y | 7 | CONFIG_MIPS_CPS=y |
9 | CONFIG_NR_CPUS=8 | 8 | CONFIG_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 | |||
146 | CONFIG_DEV_APPLETALK=m | 146 | CONFIG_DEV_APPLETALK=m |
147 | CONFIG_IPDDP=m | 147 | CONFIG_IPDDP=m |
148 | CONFIG_IPDDP_ENCAP=y | 148 | CONFIG_IPDDP_ENCAP=y |
149 | CONFIG_IPDDP_DECAP=y | ||
150 | CONFIG_X25=m | 149 | CONFIG_X25=m |
151 | CONFIG_LAPB=m | 150 | CONFIG_LAPB=m |
152 | CONFIG_ECONET=m | ||
153 | CONFIG_ECONET_AUNUDP=y | ||
154 | CONFIG_ECONET_NATIVE=y | ||
155 | CONFIG_WAN_ROUTER=m | 151 | CONFIG_WAN_ROUTER=m |
156 | CONFIG_NET_SCHED=y | 152 | CONFIG_NET_SCHED=y |
157 | CONFIG_NET_SCH_CBQ=m | 153 | CONFIG_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 | |||
259 | CONFIG_DEV_APPLETALK=m | 259 | CONFIG_DEV_APPLETALK=m |
260 | CONFIG_IPDDP=m | 260 | CONFIG_IPDDP=m |
261 | CONFIG_IPDDP_ENCAP=y | 261 | CONFIG_IPDDP_ENCAP=y |
262 | CONFIG_IPDDP_DECAP=y | ||
263 | CONFIG_X25=m | 262 | CONFIG_X25=m |
264 | CONFIG_LAPB=m | 263 | CONFIG_LAPB=m |
265 | CONFIG_WAN_ROUTER=m | 264 | CONFIG_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 | |||
240 | CONFIG_DEV_APPLETALK=m | 240 | CONFIG_DEV_APPLETALK=m |
241 | CONFIG_IPDDP=m | 241 | CONFIG_IPDDP=m |
242 | CONFIG_IPDDP_ENCAP=y | 242 | CONFIG_IPDDP_ENCAP=y |
243 | CONFIG_IPDDP_DECAP=y | ||
244 | CONFIG_X25=m | 243 | CONFIG_X25=m |
245 | CONFIG_LAPB=m | 244 | CONFIG_LAPB=m |
246 | CONFIG_ECONET=m | ||
247 | CONFIG_ECONET_AUNUDP=y | ||
248 | CONFIG_ECONET_NATIVE=y | ||
249 | CONFIG_WAN_ROUTER=m | 245 | CONFIG_WAN_ROUTER=m |
250 | CONFIG_PHONET=m | 246 | CONFIG_PHONET=m |
251 | CONFIG_IEEE802154=m | 247 | CONFIG_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 @@ | |||
1 | CONFIG_RALINK=y | ||
2 | CONFIG_SOC_MT7620=y | ||
3 | CONFIG_DTB_OMEGA2P=y | ||
4 | CONFIG_CPU_MIPS32_R2=y | ||
5 | # CONFIG_COMPACTION is not set | ||
6 | CONFIG_HZ_100=y | ||
7 | CONFIG_PREEMPT=y | ||
8 | # CONFIG_SECCOMP is not set | ||
9 | CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y | ||
10 | # CONFIG_LOCALVERSION_AUTO is not set | ||
11 | CONFIG_SYSVIPC=y | ||
12 | CONFIG_POSIX_MQUEUE=y | ||
13 | CONFIG_NO_HZ_IDLE=y | ||
14 | CONFIG_HIGH_RES_TIMERS=y | ||
15 | CONFIG_IKCONFIG=y | ||
16 | CONFIG_IKCONFIG_PROC=y | ||
17 | CONFIG_LOG_BUF_SHIFT=14 | ||
18 | CONFIG_CGROUPS=y | ||
19 | CONFIG_MEMCG=y | ||
20 | CONFIG_CGROUP_SCHED=y | ||
21 | CONFIG_CGROUP_FREEZER=y | ||
22 | CONFIG_CGROUP_DEVICE=y | ||
23 | CONFIG_CGROUP_CPUACCT=y | ||
24 | CONFIG_NAMESPACES=y | ||
25 | CONFIG_USER_NS=y | ||
26 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
27 | CONFIG_SYSCTL_SYSCALL=y | ||
28 | CONFIG_KALLSYMS_ALL=y | ||
29 | CONFIG_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 | ||
35 | CONFIG_NET=y | ||
36 | CONFIG_PACKET=y | ||
37 | CONFIG_UNIX=y | ||
38 | CONFIG_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 | ||
45 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
46 | CONFIG_DEVTMPFS=y | ||
47 | # CONFIG_FW_LOADER is not set | ||
48 | # CONFIG_ALLOW_DEV_COREDUMP is not set | ||
49 | CONFIG_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 | ||
55 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
56 | CONFIG_LEGACY_PTY_COUNT=2 | ||
57 | CONFIG_SERIAL_8250=y | ||
58 | CONFIG_SERIAL_8250_CONSOLE=y | ||
59 | CONFIG_SERIAL_8250_NR_UARTS=3 | ||
60 | CONFIG_SERIAL_8250_RUNTIME_UARTS=3 | ||
61 | CONFIG_SERIAL_OF_PLATFORM=y | ||
62 | # CONFIG_HW_RANDOM is not set | ||
63 | # CONFIG_HWMON is not set | ||
64 | # CONFIG_VGA_CONSOLE is not set | ||
65 | CONFIG_USB=y | ||
66 | CONFIG_USB_EHCI_HCD=y | ||
67 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
68 | CONFIG_MMC=y | ||
69 | # CONFIG_IOMMU_SUPPORT is not set | ||
70 | CONFIG_MEMORY=y | ||
71 | CONFIG_PHY_RALINK_USB=y | ||
72 | # CONFIG_DNOTIFY is not set | ||
73 | CONFIG_PROC_KCORE=y | ||
74 | # CONFIG_PROC_PAGE_MONITOR is not set | ||
75 | CONFIG_TMPFS=y | ||
76 | CONFIG_CONFIGFS_FS=y | ||
77 | # CONFIG_NETWORK_FILESYSTEMS is not set | ||
78 | CONFIG_NLS_CODEPAGE_437=y | ||
79 | CONFIG_NLS_CODEPAGE_737=y | ||
80 | CONFIG_NLS_CODEPAGE_775=y | ||
81 | CONFIG_NLS_CODEPAGE_850=y | ||
82 | CONFIG_NLS_CODEPAGE_852=y | ||
83 | CONFIG_NLS_CODEPAGE_855=y | ||
84 | CONFIG_NLS_CODEPAGE_857=y | ||
85 | CONFIG_NLS_CODEPAGE_860=y | ||
86 | CONFIG_NLS_CODEPAGE_861=y | ||
87 | CONFIG_NLS_CODEPAGE_862=y | ||
88 | CONFIG_NLS_CODEPAGE_863=y | ||
89 | CONFIG_NLS_CODEPAGE_864=y | ||
90 | CONFIG_NLS_CODEPAGE_865=y | ||
91 | CONFIG_NLS_CODEPAGE_866=y | ||
92 | CONFIG_NLS_CODEPAGE_869=y | ||
93 | CONFIG_NLS_CODEPAGE_936=y | ||
94 | CONFIG_NLS_CODEPAGE_950=y | ||
95 | CONFIG_NLS_CODEPAGE_932=y | ||
96 | CONFIG_NLS_CODEPAGE_949=y | ||
97 | CONFIG_NLS_CODEPAGE_874=y | ||
98 | CONFIG_NLS_ISO8859_8=y | ||
99 | CONFIG_NLS_CODEPAGE_1250=y | ||
100 | CONFIG_NLS_CODEPAGE_1251=y | ||
101 | CONFIG_NLS_ASCII=y | ||
102 | CONFIG_NLS_ISO8859_1=y | ||
103 | CONFIG_NLS_ISO8859_2=y | ||
104 | CONFIG_NLS_ISO8859_3=y | ||
105 | CONFIG_NLS_ISO8859_4=y | ||
106 | CONFIG_NLS_ISO8859_5=y | ||
107 | CONFIG_NLS_ISO8859_6=y | ||
108 | CONFIG_NLS_ISO8859_7=y | ||
109 | CONFIG_NLS_ISO8859_9=y | ||
110 | CONFIG_NLS_ISO8859_13=y | ||
111 | CONFIG_NLS_ISO8859_14=y | ||
112 | CONFIG_NLS_ISO8859_15=y | ||
113 | CONFIG_NLS_KOI8_R=y | ||
114 | CONFIG_NLS_KOI8_U=y | ||
115 | CONFIG_NLS_UTF8=y | ||
116 | CONFIG_PRINTK_TIME=y | ||
117 | CONFIG_DEBUG_INFO=y | ||
118 | CONFIG_STRIP_ASM_SYMS=y | ||
119 | CONFIG_DEBUG_FS=y | ||
120 | CONFIG_MAGIC_SYSRQ=y | ||
121 | CONFIG_PANIC_TIMEOUT=10 | ||
122 | # CONFIG_SCHED_DEBUG is not set | ||
123 | # CONFIG_DEBUG_PREEMPT is not set | ||
124 | CONFIG_STACKTRACE=y | ||
125 | # CONFIG_FTRACE is not set | ||
126 | CONFIG_CRYPTO_DEFLATE=y | ||
127 | CONFIG_CRYPTO_LZO=y | ||
128 | CONFIG_CRC16=y | ||
129 | CONFIG_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 | |||
47 | CONFIG_IP_MULTIPLE_TABLES=y | 47 | CONFIG_IP_MULTIPLE_TABLES=y |
48 | CONFIG_IP_ROUTE_MULTIPATH=y | 48 | CONFIG_IP_ROUTE_MULTIPATH=y |
49 | CONFIG_IP_ROUTE_VERBOSE=y | 49 | CONFIG_IP_ROUTE_VERBOSE=y |
50 | CONFIG_IP_PNP=y | ||
51 | CONFIG_IP_PNP_DHCP=y | ||
50 | CONFIG_IP_MROUTE=y | 52 | CONFIG_IP_MROUTE=y |
51 | CONFIG_IP_PIMSM_V1=y | 53 | CONFIG_IP_PIMSM_V1=y |
52 | CONFIG_IP_PIMSM_V2=y | 54 | CONFIG_IP_PIMSM_V2=y |
@@ -292,7 +294,8 @@ CONFIG_SQUASHFS_LZO=y | |||
292 | CONFIG_PSTORE=y | 294 | CONFIG_PSTORE=y |
293 | CONFIG_PSTORE_CONSOLE=y | 295 | CONFIG_PSTORE_CONSOLE=y |
294 | CONFIG_PSTORE_RAM=y | 296 | CONFIG_PSTORE_RAM=y |
295 | # CONFIG_NETWORK_FILESYSTEMS is not set | 297 | CONFIG_NFS_FS=y |
298 | CONFIG_ROOT_NFS=y | ||
296 | CONFIG_NLS_DEFAULT="utf8" | 299 | CONFIG_NLS_DEFAULT="utf8" |
297 | CONFIG_NLS_CODEPAGE_437=m | 300 | CONFIG_NLS_CODEPAGE_437=m |
298 | CONFIG_NLS_ASCII=m | 301 | CONFIG_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 @@ | |||
1 | CONFIG_RALINK=y | ||
2 | CONFIG_SOC_MT7620=y | ||
3 | CONFIG_DTB_VOCORE2=y | ||
4 | CONFIG_CPU_MIPS32_R2=y | ||
5 | # CONFIG_COMPACTION is not set | ||
6 | CONFIG_HZ_100=y | ||
7 | CONFIG_PREEMPT=y | ||
8 | # CONFIG_SECCOMP is not set | ||
9 | CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y | ||
10 | # CONFIG_LOCALVERSION_AUTO is not set | ||
11 | CONFIG_SYSVIPC=y | ||
12 | CONFIG_POSIX_MQUEUE=y | ||
13 | CONFIG_NO_HZ_IDLE=y | ||
14 | CONFIG_HIGH_RES_TIMERS=y | ||
15 | CONFIG_IKCONFIG=y | ||
16 | CONFIG_IKCONFIG_PROC=y | ||
17 | CONFIG_LOG_BUF_SHIFT=14 | ||
18 | CONFIG_CGROUPS=y | ||
19 | CONFIG_MEMCG=y | ||
20 | CONFIG_CGROUP_SCHED=y | ||
21 | CONFIG_CGROUP_FREEZER=y | ||
22 | CONFIG_CGROUP_DEVICE=y | ||
23 | CONFIG_CGROUP_CPUACCT=y | ||
24 | CONFIG_NAMESPACES=y | ||
25 | CONFIG_USER_NS=y | ||
26 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
27 | CONFIG_SYSCTL_SYSCALL=y | ||
28 | CONFIG_KALLSYMS_ALL=y | ||
29 | CONFIG_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 | ||
35 | CONFIG_NET=y | ||
36 | CONFIG_PACKET=y | ||
37 | CONFIG_UNIX=y | ||
38 | CONFIG_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 | ||
45 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
46 | CONFIG_DEVTMPFS=y | ||
47 | # CONFIG_FW_LOADER is not set | ||
48 | # CONFIG_ALLOW_DEV_COREDUMP is not set | ||
49 | CONFIG_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 | ||
55 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
56 | CONFIG_LEGACY_PTY_COUNT=2 | ||
57 | CONFIG_SERIAL_8250=y | ||
58 | CONFIG_SERIAL_8250_CONSOLE=y | ||
59 | CONFIG_SERIAL_8250_NR_UARTS=3 | ||
60 | CONFIG_SERIAL_8250_RUNTIME_UARTS=3 | ||
61 | CONFIG_SERIAL_OF_PLATFORM=y | ||
62 | # CONFIG_HW_RANDOM is not set | ||
63 | # CONFIG_HWMON is not set | ||
64 | # CONFIG_VGA_CONSOLE is not set | ||
65 | CONFIG_USB=y | ||
66 | CONFIG_USB_EHCI_HCD=y | ||
67 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
68 | CONFIG_MMC=y | ||
69 | # CONFIG_IOMMU_SUPPORT is not set | ||
70 | CONFIG_MEMORY=y | ||
71 | CONFIG_PHY_RALINK_USB=y | ||
72 | # CONFIG_DNOTIFY is not set | ||
73 | CONFIG_PROC_KCORE=y | ||
74 | # CONFIG_PROC_PAGE_MONITOR is not set | ||
75 | CONFIG_TMPFS=y | ||
76 | CONFIG_CONFIGFS_FS=y | ||
77 | # CONFIG_NETWORK_FILESYSTEMS is not set | ||
78 | CONFIG_NLS_CODEPAGE_437=y | ||
79 | CONFIG_NLS_CODEPAGE_737=y | ||
80 | CONFIG_NLS_CODEPAGE_775=y | ||
81 | CONFIG_NLS_CODEPAGE_850=y | ||
82 | CONFIG_NLS_CODEPAGE_852=y | ||
83 | CONFIG_NLS_CODEPAGE_855=y | ||
84 | CONFIG_NLS_CODEPAGE_857=y | ||
85 | CONFIG_NLS_CODEPAGE_860=y | ||
86 | CONFIG_NLS_CODEPAGE_861=y | ||
87 | CONFIG_NLS_CODEPAGE_862=y | ||
88 | CONFIG_NLS_CODEPAGE_863=y | ||
89 | CONFIG_NLS_CODEPAGE_864=y | ||
90 | CONFIG_NLS_CODEPAGE_865=y | ||
91 | CONFIG_NLS_CODEPAGE_866=y | ||
92 | CONFIG_NLS_CODEPAGE_869=y | ||
93 | CONFIG_NLS_CODEPAGE_936=y | ||
94 | CONFIG_NLS_CODEPAGE_950=y | ||
95 | CONFIG_NLS_CODEPAGE_932=y | ||
96 | CONFIG_NLS_CODEPAGE_949=y | ||
97 | CONFIG_NLS_CODEPAGE_874=y | ||
98 | CONFIG_NLS_ISO8859_8=y | ||
99 | CONFIG_NLS_CODEPAGE_1250=y | ||
100 | CONFIG_NLS_CODEPAGE_1251=y | ||
101 | CONFIG_NLS_ASCII=y | ||
102 | CONFIG_NLS_ISO8859_1=y | ||
103 | CONFIG_NLS_ISO8859_2=y | ||
104 | CONFIG_NLS_ISO8859_3=y | ||
105 | CONFIG_NLS_ISO8859_4=y | ||
106 | CONFIG_NLS_ISO8859_5=y | ||
107 | CONFIG_NLS_ISO8859_6=y | ||
108 | CONFIG_NLS_ISO8859_7=y | ||
109 | CONFIG_NLS_ISO8859_9=y | ||
110 | CONFIG_NLS_ISO8859_13=y | ||
111 | CONFIG_NLS_ISO8859_14=y | ||
112 | CONFIG_NLS_ISO8859_15=y | ||
113 | CONFIG_NLS_KOI8_R=y | ||
114 | CONFIG_NLS_KOI8_U=y | ||
115 | CONFIG_NLS_UTF8=y | ||
116 | CONFIG_PRINTK_TIME=y | ||
117 | CONFIG_DEBUG_INFO=y | ||
118 | CONFIG_STRIP_ASM_SYMS=y | ||
119 | CONFIG_DEBUG_FS=y | ||
120 | CONFIG_MAGIC_SYSRQ=y | ||
121 | CONFIG_PANIC_TIMEOUT=10 | ||
122 | # CONFIG_SCHED_DEBUG is not set | ||
123 | # CONFIG_DEBUG_PREEMPT is not set | ||
124 | CONFIG_STACKTRACE=y | ||
125 | # CONFIG_FTRACE is not set | ||
126 | CONFIG_CRYPTO_DEFLATE=y | ||
127 | CONFIG_CRYPTO_LZO=y | ||
128 | CONFIG_CRC16=y | ||
129 | CONFIG_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 | ||
39 | config 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 | |||
39 | endif | 45 | endif |
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/ | |||
12 | cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic | 12 | cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic |
13 | load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 | 13 | load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 |
14 | all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb | 14 | all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb |
15 | |||
16 | its-y := vmlinux.its.S | ||
17 | its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S | ||
18 | its-$(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 | |||
91 | void __init plat_fdt_relocated(void *new_location) | 94 | void __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 | |||
104 | void __init plat_mem_setup(void) | 109 | void __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 | ||
20 | int get_c0_fdc_int(void) | 21 | int 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; \ |
57 | symbol: .frame sp, 0, ra; \ | 57 | symbol: .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; \ |
68 | symbol: .frame sp, framesize, rpc; \ | 69 | symbol: .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 | ||
51 | extern struct plat_smp_ops bmips43xx_smp_ops; | 51 | extern const struct plat_smp_ops bmips43xx_smp_ops; |
52 | extern struct plat_smp_ops bmips5000_smp_ops; | 52 | extern const struct plat_smp_ops bmips5000_smp_ops; |
53 | 53 | ||
54 | static inline int register_bmips_smp_ops(void) | 54 | static 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) | 142 | static 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 | |||
152 | static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo) | ||
153 | { | ||
154 | return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >> | ||
155 | MIPS_GLOBALNUMBER_CORE_SHF; | ||
156 | } | ||
157 | |||
158 | static 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 | |||
168 | extern void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster); | ||
169 | extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core); | ||
170 | extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe); | ||
171 | |||
172 | static 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 | ||
153 | static inline unsigned long cpu_asid_inc(void) | 189 | static 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 | ||
15 | static inline void fd_cacheflush(char * addr, long size) | 15 | static 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 | ||
50 | DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); | 166 | DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); |
@@ -62,7 +178,7 @@ do { \ | |||
62 | 178 | ||
63 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | 179 | extern 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); |
66 | void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, | 182 | void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, |
67 | struct task_struct *tsk); | 183 | struct task_struct *tsk); |
68 | int process_fpemu_return(int sig, void __user *fault_addr, | 184 | int 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 | ||
635 | void __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 { | |||
23 | extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS]; | 23 | extern 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 */ |
48 | extern unsigned char ltq_boot_select(void); | 48 | extern unsigned char ltq_boot_select(void); |
49 | /* find out what caused the last cpu reset */ | ||
50 | extern int ltq_reset_cause(void); | ||
51 | /* find out the soc type */ | 49 | /* find out the soc type */ |
52 | extern int ltq_soc_type(void); | 50 | extern 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 */ |
27 | extern u32 cpu_clock_freq; | 27 | extern u32 cpu_clock_freq; |
28 | extern u32 memsize, highmemsize; | 28 | extern u32 memsize, highmemsize; |
29 | extern struct plat_smp_ops loongson3_smp_ops; | 29 | extern 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 */ |
32 | extern void __init prom_init_memory(void); | 32 | extern 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 | ||
10 | struct pci_bus; | 9 | struct 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 */ |
20 | extern void __iomem *mips_cm_base; | 22 | extern 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 */ |
23 | extern void __iomem *mips_cm_l2sync_base; | 25 | extern void __iomem *mips_cm_l2sync_base; |
@@ -80,7 +82,7 @@ static inline int mips_cm_probe(void) | |||
80 | static inline bool mips_cm_present(void) | 82 | static 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) \ |
117 | static 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) |
122 | static 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 | |
127 | static 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) { \ | 134 | GCR_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 | } \ | 142 | GCR_ACCESSOR_RW(64, 0x008, base) |
141 | \ | 143 | #define CM_GCR_BASE_GCRBASE GENMASK_ULL(47, 15) |
142 | static 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) \ | ||
151 | static inline void write32_gcr_##name(u32 value) \ | ||
152 | { \ | ||
153 | __raw_writel(value, addr_gcr_##name()); \ | ||
154 | } \ | ||
155 | \ | ||
156 | static inline void write64_gcr_##name(u64 value) \ | ||
157 | { \ | ||
158 | __raw_writeq(value, addr_gcr_##name()); \ | ||
159 | } \ | ||
160 | \ | ||
161 | static 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 */ | ||
186 | BUILD_CM_R_(config, MIPS_CM_GCB_OFS + 0x00) | ||
187 | BUILD_CM_RW(base, MIPS_CM_GCB_OFS + 0x08) | ||
188 | BUILD_CM_RW(access, MIPS_CM_GCB_OFS + 0x20) | ||
189 | BUILD_CM_R_(rev, MIPS_CM_GCB_OFS + 0x30) | ||
190 | BUILD_CM_RW(err_control, MIPS_CM_GCB_OFS + 0x38) | ||
191 | BUILD_CM_RW(error_mask, MIPS_CM_GCB_OFS + 0x40) | ||
192 | BUILD_CM_RW(error_cause, MIPS_CM_GCB_OFS + 0x48) | ||
193 | BUILD_CM_RW(error_addr, MIPS_CM_GCB_OFS + 0x50) | ||
194 | BUILD_CM_RW(error_mult, MIPS_CM_GCB_OFS + 0x58) | ||
195 | BUILD_CM_RW(l2_only_sync_base, MIPS_CM_GCB_OFS + 0x70) | ||
196 | BUILD_CM_RW(gic_base, MIPS_CM_GCB_OFS + 0x80) | ||
197 | BUILD_CM_RW(cpc_base, MIPS_CM_GCB_OFS + 0x88) | ||
198 | BUILD_CM_RW(reg0_base, MIPS_CM_GCB_OFS + 0x90) | ||
199 | BUILD_CM_RW(reg0_mask, MIPS_CM_GCB_OFS + 0x98) | ||
200 | BUILD_CM_RW(reg1_base, MIPS_CM_GCB_OFS + 0xa0) | ||
201 | BUILD_CM_RW(reg1_mask, MIPS_CM_GCB_OFS + 0xa8) | ||
202 | BUILD_CM_RW(reg2_base, MIPS_CM_GCB_OFS + 0xb0) | ||
203 | BUILD_CM_RW(reg2_mask, MIPS_CM_GCB_OFS + 0xb8) | ||
204 | BUILD_CM_RW(reg3_base, MIPS_CM_GCB_OFS + 0xc0) | ||
205 | BUILD_CM_RW(reg3_mask, MIPS_CM_GCB_OFS + 0xc8) | ||
206 | BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0) | ||
207 | BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0) | ||
208 | BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130) | ||
209 | BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150) | ||
210 | BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300) | ||
211 | BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308) | ||
212 | BUILD_CM_RW(bev_base, MIPS_CM_GCB_OFS + 0x680) | ||
213 | |||
214 | /* Core Local & Core Other register accessor functions */ | ||
215 | BUILD_CM_Cx_RW(reset_release, 0x00) | ||
216 | BUILD_CM_Cx_RW(coherence, 0x08) | ||
217 | BUILD_CM_Cx_R_(config, 0x10) | ||
218 | BUILD_CM_Cx_RW(other, 0x18) | ||
219 | BUILD_CM_Cx_RW(reset_base, 0x20) | ||
220 | BUILD_CM_Cx_R_(id, 0x28) | ||
221 | BUILD_CM_Cx_RW(reset_ext_base, 0x30) | ||
222 | BUILD_CM_Cx_R_(tcid_0_priority, 0x40) | ||
223 | BUILD_CM_Cx_R_(tcid_1_priority, 0x48) | ||
224 | BUILD_CM_Cx_R_(tcid_2_priority, 0x50) | ||
225 | BUILD_CM_Cx_R_(tcid_3_priority, 0x58) | ||
226 | BUILD_CM_Cx_R_(tcid_4_priority, 0x60) | ||
227 | BUILD_CM_Cx_R_(tcid_5_priority, 0x68) | ||
228 | BUILD_CM_Cx_R_(tcid_6_priority, 0x70) | ||
229 | BUILD_CM_Cx_R_(tcid_7_priority, 0x78) | ||
230 | BUILD_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) | 151 | GCR_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 | 155 | GCR_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) | 169 | GCR_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 | 174 | GCR_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) | 177 | GCR_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) | 183 | GCR_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 | 186 | GCR_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 | 190 | GCR_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) | 195 | GCR_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 | 200 | GCR_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) | 205 | GCR_ACCESSOR_RW(64, 0x090, reg0_base) |
309 | 206 | GCR_ACCESSOR_RW(64, 0x0a0, reg1_base) | |
310 | /* GCR_REGn_BASE register fields */ | 207 | GCR_ACCESSOR_RW(64, 0x0b0, reg2_base) |
311 | #define CM_GCR_REGn_BASE_BASEADDR_SHF 16 | 208 | GCR_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 | 212 | GCR_ACCESSOR_RW(64, 0x098, reg0_mask) |
316 | #define CM_GCR_REGn_MASK_ADDRMASK_MSK (_ULCAST_(0xffff) << 16) | 213 | GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask) |
317 | #define CM_GCR_REGn_MASK_CCAOVR_SHF 5 | 214 | GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask) |
318 | #define CM_GCR_REGn_MASK_CCAOVR_MSK (_ULCAST_(0x3) << 5) | 215 | GCR_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 */ | 227 | GCR_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 */ | 231 | GCR_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 */ | 235 | GCR_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 | 242 | GCR_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 | 246 | GCR_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 | 252 | GCR_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 */ | 257 | GCR_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 | 279 | GCR_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) | 284 | GCR_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 | 287 | GCR_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) | 290 | GCR_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 | 295 | GCR_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 | * | 300 | GCR_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 */ |
407 | static 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 | * | 315 | GCR_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 */ |
422 | static inline unsigned mips_cm_numiocu(void) | 319 | GCR_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) | 324 | GCR_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 | */ |
500 | static inline unsigned int mips_cm_vp_id(unsigned int cpu) | 400 | static 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 | */ |
519 | extern void mips_cm_lock_other(unsigned int core, unsigned int vp); | 428 | extern 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 | */ |
527 | extern void mips_cm_unlock_other(void); | 437 | extern void mips_cm_unlock_other(void); |
528 | 438 | ||
529 | #else /* !CONFIG_MIPS_CM */ | 439 | #else /* !CONFIG_MIPS_CM */ |
530 | 440 | ||
531 | static inline void mips_cm_lock_other(unsigned int core, unsigned int vp) { } | 441 | static inline void mips_cm_lock_other(unsigned int cluster, unsigned int core, |
442 | unsigned int vp, unsigned int block) { } | ||
532 | static inline void mips_cm_unlock_other(void) { } | 443 | static 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 | */ | ||
456 | static 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 */ |
18 | extern void __iomem *mips_cpc_base; | 22 | extern 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) \ |
66 | static 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) |
71 | static 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) \ |
77 | static 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 | 85 | CPC_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) | 88 | CPC_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)) \ | 91 | CPC_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) \ | 94 | CPC_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 | 97 | CPC_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) | 100 | CPC_ACCESSOR_RW(32, 0x030, pwrup_ctl) |
97 | 101 | #define CPC_PWRUP_CTL_CM_PWRUP BIT(0) | |
98 | /* GCB register accessor functions */ | 102 | |
99 | BUILD_CPC_RW(access, MIPS_CPC_GCB_OFS + 0x00) | 103 | /* CPC_CONFIG - Mirrors GCR_CONFIG */ |
100 | BUILD_CPC_RW(seqdel, MIPS_CPC_GCB_OFS + 0x08) | 104 | CPC_ACCESSOR_RW(64, 0x138, config) |
101 | BUILD_CPC_RW(rail, MIPS_CPC_GCB_OFS + 0x10) | 105 | |
102 | BUILD_CPC_RW(resetlen, MIPS_CPC_GCB_OFS + 0x18) | 106 | /* CPC_SYS_CONFIG - Control cluster endianness */ |
103 | BUILD_CPC_R_(revision, MIPS_CPC_GCB_OFS + 0x20) | 107 | CPC_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) |
106 | BUILD_CPC_Cx_RW(cmd, 0x00) | 110 | #define CPC_SYS_CONFIG_BE BIT(0) |
107 | BUILD_CPC_Cx_RW(stat_conf, 0x08) | 111 | |
108 | BUILD_CPC_Cx_RW(other, 0x10) | 112 | /* CPC_Cx_CMD - Instruct the CPC to take action on a core */ |
109 | BUILD_CPC_Cx_RW(vp_stop, 0x20) | 113 | CPC_CX_ACCESSOR_RW(32, 0x000, cmd) |
110 | BUILD_CPC_Cx_RW(vp_run, 0x28) | 114 | #define CPC_Cx_CMD GENMASK(3, 0) |
111 | BUILD_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) | 121 | CPC_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) | 140 | CPC_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) | 144 | CPC_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 | 147 | CPC_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) | 150 | CPC_CX_ACCESSOR_RW(32, 0x030, vp_running) |
151 | |||
152 | /* CPC_Cx_CONFIG - Mirrors GCR_Cx_CONFIG */ | ||
153 | CPC_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 | |||
17 | extern unsigned long __cps_access_bad_size(void) | ||
18 | __compiletime_error("Bad size for CPS accessor"); | ||
19 | |||
20 | #define CPS_ACCESSOR_A(unit, off, name) \ | ||
21 | static inline void *addr_##unit##_##name(void) \ | ||
22 | { \ | ||
23 | return mips_##unit##_base + (off); \ | ||
24 | } | ||
25 | |||
26 | #define CPS_ACCESSOR_R(unit, sz, name) \ | ||
27 | static 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) \ | ||
50 | static 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) \ | ||
75 | static 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 | \ | ||
84 | static inline void set_##unit##_##name(uint##sz##_t val) \ | ||
85 | { \ | ||
86 | change_##unit##_##name(val, val); \ | ||
87 | } \ | ||
88 | \ | ||
89 | static 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 | */ | ||
117 | static 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 | */ | ||
137 | static 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 | */ | ||
170 | static 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 | */ | ||
186 | static 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 | */ | ||
207 | static 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 */ | ||
21 | extern 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) \ | ||
53 | static inline void __iomem *addr_gic_##name(unsigned int intr) \ | ||
54 | { \ | ||
55 | return mips_gic_base + (off) + (intr * (stride)); \ | ||
56 | } \ | ||
57 | \ | ||
58 | static 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 | \ | ||
68 | static 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) \ | ||
91 | static inline void __iomem *addr_gic_##name(void) \ | ||
92 | { \ | ||
93 | return mips_gic_base + (off); \ | ||
94 | } \ | ||
95 | \ | ||
96 | static 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 | \ | ||
116 | static 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 | \ | ||
129 | static 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 */ | ||
168 | GIC_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 */ | ||
175 | GIC_ACCESSOR_RW(64, 0x010, counter) | ||
176 | GIC_ACCESSOR_RW(32, 0x010, counter_32l) | ||
177 | GIC_ACCESSOR_RW(32, 0x014, counter_32h) | ||
178 | |||
179 | /* GIC_SH_POL_* - Configures interrupt polarity */ | ||
180 | GIC_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 */ | ||
187 | GIC_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 */ | ||
192 | GIC_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 */ | ||
197 | GIC_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 */ | ||
202 | GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask) | ||
203 | |||
204 | /* GIC_SH_SMASK_* - Set shared interrupt mask bits */ | ||
205 | GIC_ACCESSOR_RW_INTR_BIT(0x380, smask) | ||
206 | |||
207 | /* GIC_SH_MASK_* - Read the current shared interrupt mask */ | ||
208 | GIC_ACCESSOR_RO_INTR_BIT(0x400, mask) | ||
209 | |||
210 | /* GIC_SH_PEND_* - Read currently pending shared interrupts */ | ||
211 | GIC_ACCESSOR_RO_INTR_BIT(0x480, pend) | ||
212 | |||
213 | /* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */ | ||
214 | GIC_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 */ | ||
220 | GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp) | ||
221 | |||
222 | /* GIC_Vx_CTL - VP-level interrupt control */ | ||
223 | GIC_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 */ | ||
231 | GIC_VX_ACCESSOR_RO(32, 0x004, pend) | ||
232 | |||
233 | /* GIC_Vx_MASK - Read the current local interrupt mask */ | ||
234 | GIC_VX_ACCESSOR_RO(32, 0x008, mask) | ||
235 | |||
236 | /* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */ | ||
237 | GIC_VX_ACCESSOR_RW(32, 0x00c, rmask) | ||
238 | |||
239 | /* GIC_Vx_SMASK - Set local interrupt mask bits */ | ||
240 | GIC_VX_ACCESSOR_RW(32, 0x010, smask) | ||
241 | |||
242 | /* GIC_Vx_*_MAP - Route local interrupts to the desired pins */ | ||
243 | GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map) | ||
244 | |||
245 | /* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */ | ||
246 | GIC_VX_ACCESSOR_RW(32, 0x040, wd_map) | ||
247 | |||
248 | /* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */ | ||
249 | GIC_VX_ACCESSOR_RW(32, 0x044, compare_map) | ||
250 | |||
251 | /* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */ | ||
252 | GIC_VX_ACCESSOR_RW(32, 0x048, timer_map) | ||
253 | |||
254 | /* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */ | ||
255 | GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map) | ||
256 | |||
257 | /* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */ | ||
258 | GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map) | ||
259 | |||
260 | /* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */ | ||
261 | GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map) | ||
262 | |||
263 | /* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */ | ||
264 | GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map) | ||
265 | |||
266 | /* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */ | ||
267 | GIC_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 */ | ||
271 | GIC_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 */ | ||
275 | GIC_VX_ACCESSOR_RW(64, 0x0a0, compare) | ||
276 | |||
277 | /* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */ | ||
278 | GIC_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 | */ | ||
293 | enum 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 | */ | ||
312 | static 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 | */ | ||
325 | extern 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 | */ | ||
335 | extern 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 | */ | ||
345 | extern 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 | */ |
85 | void nlm_init_boot_cpu(void); | 85 | void nlm_init_boot_cpu(void); |
86 | unsigned int nlm_get_cpu_frequency(void); | 86 | unsigned int nlm_get_cpu_frequency(void); |
87 | extern struct plat_smp_ops nlm_smp_ops; | 87 | extern const struct plat_smp_ops nlm_smp_ops; |
88 | extern char nlm_reset_entry[], nlm_reset_entry_end[]; | 88 | extern 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 | |||
42 | struct 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 | |||
51 | struct 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 | */ | ||
279 | void *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 | |||
258 | extern int cvmx_bootmem_free_named(char *name); | 286 | extern 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 | |||
366 | static 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 | |||
379 | static 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 | ||
363 | extern struct semaphore octeon_bootbus_sem; | 363 | extern struct semaphore octeon_bootbus_sem; |
364 | 364 | ||
365 | struct 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 | ||
38 | extern void register_smp_ops(struct plat_smp_ops *ops); | 38 | extern void register_smp_ops(const struct plat_smp_ops *ops); |
39 | 39 | ||
40 | static inline void plat_smp_setup(void) | 40 | static 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 | ||
60 | static inline void register_smp_ops(struct plat_smp_ops *ops) | 60 | static 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) | |||
66 | static inline int register_up_smp_ops(void) | 66 | static 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) | |||
79 | static inline int register_cmp_smp_ops(void) | 79 | static 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) | |||
95 | static inline int register_vsmp_smp_ops(void) | 95 | static 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 | */ |
59 | static inline void smp_send_reschedule(int cpu) | 59 | static 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 |
67 | static inline int __cpu_disable(void) | 67 | static 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 | ||
74 | static inline void __cpu_die(unsigned int cpu) | 74 | static 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 | ||
98 | static inline void arch_send_call_function_single_ipi(int cpu) | 98 | static 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 | ||
105 | static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) | 105 | static 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 | 234 | 8: |
184 | 8: 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 |
188 | 8: 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 |
7 | extern int raw_show_trace; | 9 | extern 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 | |||
23 | static __always_inline void prepare_frametrace(struct pt_regs *regs) | 33 | static __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 */ | |||
981 | struct mm16_r5_format { /* Load/store from stack pointer format */ | 981 | struct 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 | |||
35 | obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o | 35 | obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o |
36 | obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o | 36 | obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o |
37 | 37 | ||
38 | obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o | 38 | sw-y := r4k_switch.o |
39 | obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o | 39 | sw-$(CONFIG_CPU_R3000) := r2300_switch.o |
40 | obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o | 40 | sw-$(CONFIG_CPU_TX39XX) := r2300_switch.o |
41 | obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o | 41 | sw-$(CONFIG_CPU_CAVIUM_OCTEON) := octeon_switch.o |
42 | obj-$(CONFIG_CPU_CAVIUM_OCTEON) += r4k_fpu.o octeon_switch.o | 42 | obj-y += $(sw-y) |
43 | |||
44 | obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o | ||
45 | obj-$(CONFIG_CPU_R3000) += r2300_fpu.o | ||
46 | obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o | ||
43 | 47 | ||
44 | obj-$(CONFIG_SMP) += smp.o | 48 | obj-$(CONFIG_SMP) += smp.o |
45 | obj-$(CONFIG_SMP_UP) += smp-up.o | 49 | obj-$(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 | ||
329 | int mips_dsp_disabled; | 329 | static int mips_dsp_disabled; |
330 | 330 | ||
331 | static int __init dsp_disable(char *s) | 331 | static 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 | |||
2102 | void 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 | |||
2112 | void 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 | |||
2121 | void 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 |
151 | BUILD_ROLLBACK_PROLOGUE handle_int | 151 | BUILD_ROLLBACK_PROLOGUE handle_int |
152 | NESTED(handle_int, PT_SIZE, sp) | 152 | NESTED(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) | |||
181 | 1: | 182 | 1: |
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 | */ |
270 | BUILD_ROLLBACK_PROLOGUE except_vec_vi | 271 | BUILD_ROLLBACK_PROLOGUE except_vec_vi |
271 | NESTED(except_vec_vi, 0, sp) | 272 | NESTED(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 | ||
398 | NESTED(nmi_handler, PT_SIZE, sp) | 399 | NESTED(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 | ||
18 | void __iomem *mips_cm_base; | 18 | void __iomem *mips_gcr_base; |
19 | void __iomem *mips_cm_l2sync_base; | 19 | void __iomem *mips_cm_l2sync_base; |
20 | int mips_cm_is64; | 20 | int 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 | ||
262 | void mips_cm_lock_other(unsigned int core, unsigned int vp) | 260 | void 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(¤t_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(¤t_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 | ||
18 | void __iomem *mips_cpc_base; | 17 | void __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(¤t_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(¤t_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 | ||
49 | DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2emustats); | 49 | #ifdef CONFIG_DEBUG_FS |
50 | DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2bdemustats); | 50 | static DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2emustats); |
51 | DEFINE_PER_CPU(struct mips_r2br_emulator_stats, mipsr2bremustats); | 51 | static DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2bdemustats); |
52 | static DEFINE_PER_CPU(struct mips_r2br_emulator_stats, mipsr2bremustats); | ||
53 | #endif | ||
52 | 54 | ||
53 | extern const unsigned int fpucondbit[8]; | 55 | extern 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 */ |
603 | static struct r2_decoder_table spec_op_table[] = { | 605 | static 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 */ |
870 | static struct r2_decoder_table spec2_op_table[] = { | 872 | static 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 | ||
883 | static inline int mipsr2_find_op_func(struct pt_regs *regs, u32 inst, | 885 | static 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 */ |
52 | DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT); | 51 | static 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) | |||
114 | int cps_pm_enter_state(enum cps_pm_state state) | 113 | int 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(¤t_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: | |||
640 | static int cps_pm_online_cpu(unsigned int cpu) | 639 | static 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 | ||
316 | static inline int is_sp_move_ins(union mips_instruction *ip) | 316 | static 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 | */ | ||
41 | LEAF(_save_fp) | ||
42 | EXPORT_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 | */ | ||
50 | LEAF(_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 | |||
66 | LEAF(_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 | */ | ||
75 | LEAF(_save_fp) | ||
76 | EXPORT_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 | */ | ||
84 | LEAF(_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 | |||
100 | LEAF(_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 | */ | ||
41 | LEAF(_save_fp) | ||
42 | EXPORT_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 | */ | ||
54 | LEAF(_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 | */ | ||
68 | LEAF(_save_msa) | ||
69 | EXPORT_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 | */ | ||
77 | LEAF(_restore_msa) | ||
78 | msa_restore_all a0 | ||
79 | jr ra | ||
80 | END(_restore_msa) | ||
81 | |||
82 | LEAF(_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 | |||
100 | LEAF(_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 | ||
131 | 1: | ||
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 | ||
207 | 1: .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 | */ | ||
72 | LEAF(_save_fp) | ||
73 | EXPORT_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 | */ | ||
85 | LEAF(_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 | */ | ||
99 | LEAF(_save_msa) | ||
100 | EXPORT_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 | */ | ||
108 | LEAF(_restore_msa) | ||
109 | msa_restore_all a0 | ||
110 | jr ra | ||
111 | END(_restore_msa) | ||
112 | |||
113 | LEAF(_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 | |||
131 | LEAF(_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 | ||
162 | 1: | ||
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 | ||
238 | 1: .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) | ||
58 | 1: 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 | ||
95 | 1: 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 | */ |
182 | static void bmips_boot_secondary(int cpu, struct task_struct *idle) | 182 | static 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(¤t_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 | ||
412 | struct plat_smp_ops bmips43xx_smp_ops = { | 414 | const 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 | ||
426 | struct plat_smp_ops bmips5000_smp_ops = { | 428 | const 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 | */ |
81 | static void cmp_boot_secondary(int cpu, struct task_struct *idle) | 80 | static 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 | ||
151 | struct plat_smp_ops cmp_smp_ops = { | 151 | const 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 | } |
42 | early_param("nothreads", setup_nothreads); | 40 | early_param("nothreads", setup_nothreads); |
43 | 41 | ||
44 | static unsigned core_vpe_count(unsigned core) | 42 | static 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 | ||
61 | static void __init cps_smp_setup(void) | 50 | static 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) | |||
121 | static void __init cps_prepare_cpus(unsigned int max_cpus) | 122 | static 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(¤t_cpu_data)].vpe_mask, |
193 | 1 << cpu_vpe_id(¤t_cpu_data)); | 198 | 1 << cpu_vpe_id(¤t_cpu_data)); |
194 | 199 | ||
195 | return; | 200 | return; |
@@ -212,11 +217,11 @@ err_out: | |||
212 | 217 | ||
213 | static void boot_core(unsigned int core, unsigned int vpe_id) | 218 | static 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 | ||
286 | static void remote_vpe_boot(void *dummy) | 290 | static void remote_vpe_boot(void *dummy) |
287 | { | 291 | { |
288 | unsigned core = current_cpu_data.core; | 292 | unsigned core = cpu_core(¤t_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(¤t_cpu_data)); | 295 | mips_cps_boot_vpes(core_cfg, cpu_vpe_id(¤t_cpu_data)); |
292 | } | 296 | } |
293 | 297 | ||
294 | static void cps_boot_secondary(int cpu, struct task_struct *idle) | 298 | static 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(¤t_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); |
350 | out: | 358 | out: |
351 | preempt_enable(); | 359 | preempt_enable(); |
360 | return 0; | ||
352 | } | 361 | } |
353 | 362 | ||
354 | static void cps_init_secondary(void) | 363 | static 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(¤t_cpu_data)]; |
406 | atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask); | 415 | atomic_sub(1 << cpu_vpe_id(¤t_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 | ||
489 | static void cps_cpu_die(unsigned int cpu) | 500 | static 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 | ||
574 | static struct plat_smp_ops cps_smp_ops = { | 586 | static 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 | ||
588 | bool mips_cps_smp_in_use(void) | 600 | bool 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 | ||
40 | static void __init smvp_copy_vpe_config(void) | 40 | static 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 | ||
119 | static void vsmp_init_secondary(void) | 119 | static 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 | */ |
155 | static void vsmp_boot_secondary(int cpu, struct task_struct *idle) | 153 | static 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 | ||
242 | struct plat_smp_ops vsmp_smp_ops = { | 242 | const 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 | */ |
42 | static void up_boot_secondary(int cpu, struct task_struct *idle) | 42 | static int up_boot_secondary(int cpu, struct task_struct *idle) |
43 | { | 43 | { |
44 | return 0; | ||
44 | } | 45 | } |
45 | 46 | ||
46 | static void __init up_smp_setup(void) | 47 | static 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 | ||
66 | struct plat_smp_ops up_smp_ops = { | 67 | const 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 | ||
149 | struct plat_smp_ops *mp_ops; | 147 | const struct plat_smp_ops *mp_ops; |
150 | EXPORT_SYMBOL(mp_ops); | 148 | EXPORT_SYMBOL(mp_ops); |
151 | 149 | ||
152 | void register_smp_ops(struct plat_smp_ops *ops) | 150 | void 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 | ||
442 | int __cpu_up(unsigned int cpu, struct task_struct *tidle) | 440 | int __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); | |||
72 | unsigned int mips_hpt_frequency; | 72 | unsigned int mips_hpt_frequency; |
73 | EXPORT_SYMBOL_GPL(mips_hpt_frequency); | 73 | EXPORT_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 | */ | ||
84 | void __init plat_timer_setup(void) | ||
85 | { | ||
86 | BUG(); | ||
87 | } | ||
88 | |||
89 | static __init int cpu_has_mfc0_count_bug(void) | 75 | static __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: | |||
1378 | const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; | 1378 | const 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. */ |
1381 | const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; | 1381 | static const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; |
1382 | 1382 | ||
1383 | static void emulate_load_store_microMIPS(struct pt_regs *regs, | 1383 | static 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 | ||
21 | config SOC_FALCON | 23 | config 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 */ | ||
28 | unsigned char ltq_boot_select(void) | 22 | unsigned 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 */ | ||
34 | int ltq_reset_cause(void) | ||
35 | { | ||
36 | return ltq_sys1_r32(SYS1_CPU0RS) & CPU0RS_MASK; | ||
37 | } | 25 | } |
38 | EXPORT_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 | ||
65 | int gic_present; | ||
66 | #endif | ||
67 | |||
68 | static int exin_avail; | 64 | static int exin_avail; |
69 | static u32 ltq_eiu_irq[MAX_EIU]; | 65 | static u32 ltq_eiu_irq[MAX_EIU]; |
70 | static void __iomem *ltq_icu_membase[MAX_IM]; | 66 | static 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 | ||
118 | int __init plat_of_setup(void) | 118 | int __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 | ||
123 | arch_initcall(plat_of_setup); | 123 | arch_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 @@ | |||
1 | obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o | 1 | obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o |
2 | 2 | ||
3 | obj-y += vmmc.o | 3 | obj-y += vmmc.o |
4 | |||
5 | obj-$(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 */ | ||
99 | static void __iomem *ltq_rcu_membase; | ||
100 | static struct device_node *ltq_rcu_np; | ||
101 | static DEFINE_SPINLOCK(ltq_rcu_lock); | ||
102 | |||
103 | static void ltq_rcu_w32(uint32_t val, uint32_t reg_off) | ||
104 | { | ||
105 | ltq_w32(val, ltq_rcu_membase + reg_off); | ||
106 | } | ||
107 | |||
108 | static uint32_t ltq_rcu_r32(uint32_t reg_off) | ||
109 | { | ||
110 | return ltq_r32(ltq_rcu_membase + reg_off); | ||
111 | } | ||
112 | |||
113 | static 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(<q_rcu_lock, flags); | ||
118 | ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off); | ||
119 | spin_unlock_irqrestore(<q_rcu_lock, flags); | ||
120 | } | ||
121 | |||
122 | /* This function is used by the watchdog driver */ | ||
123 | int ltq_reset_cause(void) | ||
124 | { | ||
125 | u32 val = ltq_rcu_r32(RCU_RST_STAT); | ||
126 | return val >> RCU_STAT_SHIFT; | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(ltq_reset_cause); | ||
129 | |||
130 | /* allow platform code to find out what source we booted from */ | ||
131 | unsigned 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 | |||
141 | struct ltq_gphy_reset { | ||
142 | u32 rd; | ||
143 | u32 addr; | ||
144 | }; | ||
145 | |||
146 | /* reset / boot a gphy */ | ||
147 | static 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 */ | ||
153 | static 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 */ | ||
160 | static 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 | |||
167 | static 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 */ | ||
176 | int 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 */ | ||
217 | void 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 | |||
224 | static 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 | |||
239 | static 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 | |||
254 | static 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 | |||
261 | static const struct reset_control_ops reset_ops = { | ||
262 | .reset = ltq_reset_device, | ||
263 | .assert = ltq_assert_device, | ||
264 | .deassert = ltq_deassert_device, | ||
265 | }; | ||
266 | |||
267 | static 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 | |||
274 | void 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 | |||
284 | static 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 | |||
298 | static void ltq_machine_halt(void) | ||
299 | { | ||
300 | local_irq_disable(); | ||
301 | unreachable(); | ||
302 | } | ||
303 | |||
304 | static void ltq_machine_power_off(void) | ||
305 | { | ||
306 | local_irq_disable(); | ||
307 | unreachable(); | ||
308 | } | ||
309 | |||
310 | static 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 | |||
349 | static 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 | |||
387 | arch_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 | |||
155 | static void __iomem *pmu_membase; | 148 | static void __iomem *pmu_membase; |
156 | static void __iomem *ltq_xbar_membase; | ||
157 | void __iomem *ltq_cgu_membase; | 149 | void __iomem *ltq_cgu_membase; |
158 | void __iomem *ltq_ebu_membase; | 150 | void __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 | ||
296 | static 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 */ |
307 | static int clkout_enable(struct clk *clk) | 289 | static 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 | |||
21 | static 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 | |||
80 | static 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 | |||
101 | static const struct of_device_id xway_phy_match[] = { | ||
102 | { .compatible = "lantiq,phy-xrx200" }, | ||
103 | {}, | ||
104 | }; | ||
105 | |||
106 | static 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 | }; | ||
113 | builtin_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 | ||
9 | obj-y += iomap.o | 9 | obj-y += iomap.o iomap_copy.o |
10 | obj-$(CONFIG_PCI) += iomap-pci.o | 10 | obj-$(CONFIG_PCI) += iomap-pci.o |
11 | lib-$(CONFIG_GENERIC_CSUM) := $(filter-out csum_partial.o, $(lib-y)) | 11 | lib-$(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 | */ | ||
29 | void __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 | } | ||
42 | EXPORT_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 | ||
81 | unsigned long clk_get_rate(struct clk *clk) | 81 | unsigned 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 | } |
85 | EXPORT_SYMBOL(clk_get_rate); | 88 | EXPORT_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 | */ |
402 | static void loongson3_boot_secondary(int cpu, struct task_struct *idle) | 403 | static 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 | ||
698 | static int loongson3_disable_clock(unsigned int cpu) | 700 | static 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 | ||
712 | static int loongson3_enable_clock(unsigned int cpu) | 714 | static 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 | ||
737 | struct plat_smp_ops loongson3_smp_ops = { | 739 | const 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 | ||
5 | obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \ | 5 | obj-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 | ||
12 | lib-y += ieee754d.o \ | 14 | lib-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 | ||
60 | static int fpux_emu(struct pt_regs *, | 60 | static 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) \ |
836 | do { \ | 836 | do { \ |
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 | ||
975 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 975 | static 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 | } |
1232 | branch_common: | 1234 | branch_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); | |||
1460 | DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); | 1463 | DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); |
1461 | 1464 | ||
1462 | static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 1465 | static 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 | */ |
2555 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 2815 | int 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 | ||
121 | union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) | 147 | union 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 | ||
121 | union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) | 147 | union 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 | ||
17 | enum maddf_flags { | 17 | |
18 | maddf_negate_product = 1 << 0, | 18 | /* 128 bits shift right logical with rounding. */ |
19 | }; | 19 | void 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 | ||
21 | static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, | 43 | static 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 | ||
275 | union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | 337 | union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, |
@@ -281,5 +343,5 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | |||
281 | union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, | 343 | union 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 | |||
25 | union 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); | |||
67 | union ieee754sp ieee754sp_fint(int x); | 67 | union ieee754sp ieee754sp_fint(int x); |
68 | union ieee754sp ieee754sp_flong(s64 x); | 68 | union ieee754sp ieee754sp_flong(s64 x); |
69 | union ieee754sp ieee754sp_fdp(union ieee754dp x); | 69 | union ieee754sp ieee754sp_fdp(union ieee754dp x); |
70 | union ieee754sp ieee754sp_rint(union ieee754sp x); | ||
70 | 71 | ||
71 | int ieee754sp_tint(union ieee754sp x); | 72 | int ieee754sp_tint(union ieee754sp x); |
72 | s64 ieee754sp_tlong(union ieee754sp x); | 73 | s64 ieee754sp_tlong(union ieee754sp x); |
@@ -101,6 +102,7 @@ union ieee754dp ieee754dp_neg(union ieee754dp x); | |||
101 | union ieee754dp ieee754dp_fint(int x); | 102 | union ieee754dp ieee754dp_fint(int x); |
102 | union ieee754dp ieee754dp_flong(s64 x); | 103 | union ieee754dp ieee754dp_flong(s64 x); |
103 | union ieee754dp ieee754dp_fsp(union ieee754sp x); | 104 | union ieee754dp ieee754dp_fsp(union ieee754sp x); |
105 | union ieee754dp ieee754dp_rint(union ieee754dp x); | ||
104 | 106 | ||
105 | int ieee754dp_tint(union ieee754dp x); | 107 | int ieee754dp_tint(union ieee754dp x); |
106 | s64 ieee754dp_tlong(union ieee754dp x); | 108 | s64 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 | ||
29 | enum maddf_flags { | ||
30 | MADDF_NEGATE_PRODUCT = 1 << 0, | ||
31 | }; | ||
32 | |||
29 | static inline void ieee754_clearcx(void) | 33 | static 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 | } |
29 | DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n"); | 29 | DEFINE_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 | */ | ||
39 | static 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 | |||
51 | static 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 | |||
185 | static int fpuemustats_clear_open(struct inode *inode, struct file *file) | ||
186 | { | ||
187 | return single_open(file, fpuemustats_clear_show, inode->i_private); | ||
188 | } | ||
189 | |||
190 | static 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 | |||
31 | static int __init debugfs_fpuemu(void) | 197 | static 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) \ |
45 | do { \ | 221 | do { \ |
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) \ | ||
249 | do { \ | ||
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 | } |
68 | arch_initcall(debugfs_fpuemu); | 378 | arch_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 | ||
121 | union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) | 147 | union 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 | ||
121 | union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) | 147 | union 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 | ||
17 | enum maddf_flags { | ||
18 | maddf_negate_product = 1 << 0, | ||
19 | }; | ||
20 | 17 | ||
21 | static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, | 18 | static 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, | |||
275 | union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, | 260 | union 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 | |||
25 | union 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. */ |
25 | void (*flush_cache_all)(void); | 26 | void (*flush_cache_all)(void); |
@@ -44,7 +45,6 @@ void (*__flush_cache_vunmap)(void); | |||
44 | 45 | ||
45 | void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); | 46 | void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); |
46 | EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); | 47 | EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); |
47 | void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size); | ||
48 | 48 | ||
49 | /* MIPS specific cache operations */ | 49 | /* MIPS specific cache operations */ |
50 | void (*flush_cache_sigtramp)(unsigned long addr); | 50 | void (*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 | ||
130 | static 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 | |||
147 | static void *mips_dma_alloc_coherent(struct device *dev, size_t size, | 130 | static 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 | |||
184 | static 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 | |||
191 | static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, | 160 | static 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 | ||
412 | int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 376 | static 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 | ||
417 | int mips_dma_supported(struct device *dev, u64 mask) | 381 | static 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 | ||
79 | static void mips_sc_prefetch_disable(void) | 77 | static 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 | ||
96 | static bool mips_sc_prefetch_is_enabled(void) | 87 | static 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 | ||
109 | static struct bcache_ops mips_sc_ops = { | 100 | static 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(¤t_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; | |||
147 | unsigned long nlm_next_sp; | 147 | unsigned long nlm_next_sp; |
148 | static cpumask_t phys_cpu_present_mask; | 148 | static cpumask_t phys_cpu_present_mask; |
149 | 149 | ||
150 | void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) | 150 | int 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 | ||
166 | void __init nlm_smp_setup(void) | 168 | void __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 | ||
275 | struct plat_smp_ops nlm_smp_ops = { | 277 | const 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 |
39 | static int cpu_has_mipsmt_pertccounters; | 39 | static 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(¤t_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(¤t_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 | ||
103 | static void paravirt_boot_secondary(int cpu, struct task_struct *idle) | 103 | static 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 | ||
110 | static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id) | 111 | static 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 | ||
136 | struct plat_smp_ops paravirt_smp_ops = { | 137 | const 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 | ||
17 | extern struct plat_smp_ops paravirt_smp_ops; | 17 | extern const struct plat_smp_ops paravirt_smp_ops; |
18 | 18 | ||
19 | const char *get_system_type(void) | 19 | const 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 | ||
20 | unsigned int get_c0_compare_int(void) | 20 | unsigned 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 | |||
85 | endchoice | 95 | endchoice |
86 | 96 | ||
87 | endif | 97 | endif |
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 | ||
54 | unsigned long clk_get_rate(struct clk *clk) | 54 | unsigned 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 | } |
58 | EXPORT_SYMBOL_GPL(clk_get_rate); | 61 | EXPORT_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 | ||
16 | int get_c0_perfcount_int(void) | 16 | int 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 | */ |
198 | static void ip27_boot_secondary(int cpu, struct task_struct *idle) | 198 | static 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 | ||
208 | static void __init ip27_smp_setup(void) | 209 | static 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 | ||
234 | struct plat_smp_ops ip27_smp_ops = { | 235 | const 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 | */ |
120 | static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) | 120 | static 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 | ||
160 | struct plat_smp_ops bcm1480_smp_ops = { | 161 | const 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 | ||
232 | extern struct plat_smp_ops sb_smp_ops; | 232 | extern const struct plat_smp_ops sb_smp_ops; |
233 | extern struct plat_smp_ops bcm1480_smp_ops; | 233 | extern 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 | */ |
109 | static void sb1250_boot_secondary(int cpu, struct task_struct *idle) | 109 | static 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 | ||
149 | struct plat_smp_ops sb_smp_ops = { | 150 | const 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 | |||
26 | srctree="$1" | ||
27 | objtree="$2" | ||
28 | ref_cfg="$3" | ||
29 | cfg="$4" | ||
30 | boards_origin="$5" | ||
31 | shift 5 | ||
32 | |||
33 | cd "${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. | ||
38 | case ${boards_origin} in | ||
39 | "command line") | ||
40 | print_skipped=1 | ||
41 | ;; | ||
42 | environment*) | ||
43 | print_skipped=1 | ||
44 | ;; | ||
45 | *) | ||
46 | print_skipped=0 | ||
47 | ;; | ||
48 | esac | ||
49 | |||
50 | for 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)' | ||
90 | done | ||
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 | ||
21 | LEAF(__vdso_rt_sigreturn) | 21 | LEAF(__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 | ||
36 | LEAF(__vdso_sigreturn) | 31 | LEAF(__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 | ||
20 | static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); | 20 | static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); |
21 | static int gic_timer_irq; | 21 | static int gic_timer_irq; |
22 | static unsigned int gic_frequency; | 22 | static unsigned int gic_frequency; |
23 | 23 | ||
24 | static 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 | |||
24 | static int gic_next_event(unsigned long delta, struct clock_event_device *evt) | 40 | static 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 | ||
140 | static int __init __gic_clocksource_init(void) | 160 | static 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 | ||
26 | unsigned int gic_present; | 26 | #define GIC_MAX_INTRS 256 |
27 | #define GIC_MAX_LONGS BITS_TO_LONGS(GIC_MAX_INTRS) | ||
27 | 28 | ||
28 | struct 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 | |||
43 | void __iomem *mips_gic_base; | ||
31 | 44 | ||
32 | static unsigned long __gic_base_addr; | 45 | DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks); |
33 | 46 | ||
34 | static void __iomem *gic_base; | ||
35 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | ||
36 | static DEFINE_SPINLOCK(gic_lock); | 47 | static DEFINE_SPINLOCK(gic_lock); |
37 | static struct irq_domain *gic_irq_domain; | 48 | static struct irq_domain *gic_irq_domain; |
38 | static struct irq_domain *gic_ipi_domain; | 49 | static struct irq_domain *gic_ipi_domain; |
@@ -44,202 +55,13 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; | |||
44 | DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS); | 55 | DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS); |
45 | DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS); | 56 | DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS); |
46 | 57 | ||
47 | static void __gic_irq_dispatch(void); | 58 | static void gic_clear_pcpu_masks(unsigned int intr) |
48 | |||
49 | static inline u32 gic_read32(unsigned int reg) | ||
50 | { | ||
51 | return __raw_readl(gic_base + reg); | ||
52 | } | ||
53 | |||
54 | static inline u64 gic_read64(unsigned int reg) | ||
55 | { | ||
56 | return __raw_readq(gic_base + reg); | ||
57 | } | ||
58 | |||
59 | static 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 | |||
67 | static inline void gic_write32(unsigned int reg, u32 val) | ||
68 | { | ||
69 | return __raw_writel(val, gic_base + reg); | ||
70 | } | ||
71 | |||
72 | static inline void gic_write64(unsigned int reg, u64 val) | ||
73 | { | ||
74 | return __raw_writeq(val, gic_base + reg); | ||
75 | } | ||
76 | |||
77 | static 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 | |||
85 | static 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 | |||
96 | static 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 | |||
102 | static 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 | |||
108 | static 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 | |||
115 | static 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 | |||
122 | static 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 | |||
129 | static 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 | |||
135 | static 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 | ||
143 | u64 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 | |||
159 | unsigned 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 | |||
170 | void 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 | |||
182 | void 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 | |||
202 | u64 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 | |||
215 | void 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 | |||
225 | void 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 | |||
237 | unsigned 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 | ||
245 | static bool gic_local_irq_is_routable(int intr) | 67 | static 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 | ||
279 | static void gic_send_ipi(struct irq_data *d, unsigned int cpu) | 100 | static 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 | ||
286 | int gic_get_c0_compare_int(void) | 107 | int 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 | ||
319 | int 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 | |||
330 | static void gic_handle_shared_int(bool chained) | 140 | static 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 | ||
372 | static void gic_mask_irq(struct irq_data *d) | 168 | static 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 | ||
377 | static void gic_unmask_irq(struct irq_data *d) | 176 | static 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 | ||
382 | static void gic_ack_irq(struct irq_data *d) | 189 | static 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 | ||
389 | static int gic_set_type(struct irq_data *d, unsigned int type) | 196 | static 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 | ||
524 | static void gic_unmask_local_irq(struct irq_data *d) | 327 | static 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 | ||
531 | static struct irq_chip gic_local_irq_controller = { | 334 | static 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 | ||
585 | static 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 | |||
611 | static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, | 386 | static 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 | ||
669 | static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, | 419 | static 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 | ||
888 | static void __init __gic_init(unsigned long gic_base_addr, | 636 | |
889 | unsigned long gic_addrspace_size, | 637 | static 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 | |||
981 | void __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 | ||
988 | static 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 | } |
1038 | IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init); | 784 | IRQCHIP_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 | */ | ||
134 | static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data) | 139 | static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data) |
135 | { | 140 | { |
141 | disable_irq_nosync(irq); | ||
142 | return IRQ_WAKE_THREAD; | ||
143 | } | ||
144 | |||
145 | static 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" | |||
44 | source "drivers/phy/amlogic/Kconfig" | 44 | source "drivers/phy/amlogic/Kconfig" |
45 | source "drivers/phy/broadcom/Kconfig" | 45 | source "drivers/phy/broadcom/Kconfig" |
46 | source "drivers/phy/hisilicon/Kconfig" | 46 | source "drivers/phy/hisilicon/Kconfig" |
47 | source "drivers/phy/lantiq/Kconfig" | ||
47 | source "drivers/phy/marvell/Kconfig" | 48 | source "drivers/phy/marvell/Kconfig" |
48 | source "drivers/phy/mediatek/Kconfig" | 49 | source "drivers/phy/mediatek/Kconfig" |
49 | source "drivers/phy/motorola/Kconfig" | 50 | source "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 | |||
6 | obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o | 6 | obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o |
7 | obj-$(CONFIG_PHY_XGENE) += phy-xgene.o | 7 | obj-$(CONFIG_PHY_XGENE) += phy-xgene.o |
8 | obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o | 8 | obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o |
9 | |||
10 | obj-$(CONFIG_ARCH_SUNXI) += allwinner/ | 9 | obj-$(CONFIG_ARCH_SUNXI) += allwinner/ |
11 | obj-$(CONFIG_ARCH_MESON) += amlogic/ | 10 | obj-$(CONFIG_ARCH_MESON) += amlogic/ |
11 | obj-$(CONFIG_LANTIQ) += lantiq/ | ||
12 | obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ | 12 | obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ |
13 | obj-$(CONFIG_ARCH_RENESAS) += renesas/ | 13 | obj-$(CONFIG_ARCH_RENESAS) += renesas/ |
14 | obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ | 14 | obj-$(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 | # | ||
4 | config 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 | |||
31 | struct ltq_rcu_usb2_bits { | ||
32 | u8 hostmode; | ||
33 | u8 slave_endianness; | ||
34 | u8 host_endianness; | ||
35 | bool have_ana_cfg; | ||
36 | }; | ||
37 | |||
38 | struct 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 | |||
50 | static 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 | |||
57 | static 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 | |||
64 | static 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 | |||
71 | static 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 | }; | ||
94 | MODULE_DEVICE_TABLE(of, ltq_rcu_usb2_phy_of_match); | ||
95 | |||
96 | static 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 | |||
121 | static 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 | |||
136 | static 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 | |||
147 | static 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 | |||
154 | static 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 | |||
205 | static 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, <q_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 | |||
243 | static 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 | }; | ||
250 | module_platform_driver(ltq_rcu_usb2_phy_driver); | ||
251 | |||
252 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | ||
253 | MODULE_DESCRIPTION("Lantiq XWAY USB2 PHY driver"); | ||
254 | MODULE_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 | ||
50 | config 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 | |||
50 | config RESET_LPC18XX | 56 | config 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 | |||
7 | obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o | 7 | obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o |
8 | obj-$(CONFIG_RESET_HSDK_V1) += reset-hsdk-v1.o | 8 | obj-$(CONFIG_RESET_HSDK_V1) += reset-hsdk-v1.o |
9 | obj-$(CONFIG_RESET_IMX7) += reset-imx7.o | 9 | obj-$(CONFIG_RESET_IMX7) += reset-imx7.o |
10 | obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o | ||
10 | obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o | 11 | obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o |
11 | obj-$(CONFIG_RESET_MESON) += reset-meson.o | 12 | obj-$(CONFIG_RESET_MESON) += reset-meson.o |
12 | obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o | 13 | obj-$(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 | |||
23 | struct 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 | |||
31 | static 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 | |||
37 | static 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 | |||
52 | static 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 | |||
70 | static 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 | |||
94 | static 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 | |||
100 | static 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 | |||
106 | static 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 | |||
118 | static 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 | |||
125 | static 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 | |||
154 | static 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 | |||
168 | static 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 | |||
194 | static const struct of_device_id lantiq_rcu_reset_dt_ids[] = { | ||
195 | { .compatible = "lantiq,danube-reset", }, | ||
196 | { .compatible = "lantiq,xrx200-reset", }, | ||
197 | { }, | ||
198 | }; | ||
199 | MODULE_DEVICE_TABLE(of, lantiq_rcu_reset_dt_ids); | ||
200 | |||
201 | static 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 | }; | ||
208 | module_platform_driver(lantiq_rcu_reset_driver); | ||
209 | |||
210 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | ||
211 | MODULE_DESCRIPTION("Lantiq XWAY RCU Reset Controller Driver"); | ||
212 | MODULE_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/ | |||
9 | obj-$(CONFIG_MACH_DOVE) += dove/ | 9 | obj-$(CONFIG_MACH_DOVE) += dove/ |
10 | obj-y += fsl/ | 10 | obj-y += fsl/ |
11 | obj-$(CONFIG_ARCH_MXC) += imx/ | 11 | obj-$(CONFIG_ARCH_MXC) += imx/ |
12 | obj-$(CONFIG_SOC_XWAY) += lantiq/ | ||
12 | obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ | 13 | obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ |
13 | obj-$(CONFIG_ARCH_MESON) += amlogic/ | 14 | obj-$(CONFIG_ARCH_MESON) += amlogic/ |
14 | obj-$(CONFIG_ARCH_QCOM) += qcom/ | 15 | obj-$(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 @@ | |||
1 | obj-y += fpi-bus.o | ||
2 | obj-$(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 | |||
29 | static 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 | |||
70 | static const struct of_device_id ltq_fpi_match[] = { | ||
71 | { .compatible = "lantiq,xrx200-fpi" }, | ||
72 | {}, | ||
73 | }; | ||
74 | MODULE_DEVICE_TABLE(of, ltq_fpi_match); | ||
75 | |||
76 | static 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 | |||
84 | module_platform_driver(ltq_fpi_driver); | ||
85 | |||
86 | MODULE_DESCRIPTION("Lantiq FPI bus driver"); | ||
87 | MODULE_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 | |||
29 | struct 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 | |||
38 | struct xway_gphy_match_data { | ||
39 | char *fe_firmware_name; | ||
40 | char *ge_firmware_name; | ||
41 | }; | ||
42 | |||
43 | static 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 | |||
48 | static 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 | |||
53 | static 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 | |||
58 | static 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 | }; | ||
65 | MODULE_DEVICE_TABLE(of, xway_gphy_match); | ||
66 | |||
67 | static 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 | |||
72 | static 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 | |||
85 | static 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 | |||
122 | static 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 | |||
175 | static 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 | |||
221 | static 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 | |||
241 | static 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 | |||
250 | module_platform_driver(xway_gphy_driver); | ||
251 | |||
252 | MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin"); | ||
253 | MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin"); | ||
254 | MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin"); | ||
255 | MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin"); | ||
256 | MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin"); | ||
257 | MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin"); | ||
258 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | ||
259 | MODULE_DESCRIPTION("Lantiq XWAY GPHY Firmware Loader"); | ||
260 | MODULE_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 = <q_wdt_fops, | 198 | .fops = <q_wdt_fops, |
187 | }; | 199 | }; |
188 | 200 | ||
201 | typedef int (*ltq_wdt_bootstatus_set)(struct platform_device *pdev); | ||
202 | |||
203 | static 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 | |||
224 | static 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 | |||
189 | static int | 246 | static int |
190 | ltq_wdt_probe(struct platform_device *pdev) | 247 | ltq_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(<q_wdt_miscdev); | 275 | return misc_register(<q_wdt_miscdev); |
214 | } | 276 | } |
@@ -222,7 +284,9 @@ ltq_wdt_remove(struct platform_device *pdev) | |||
222 | } | 284 | } |
223 | 285 | ||
224 | static const struct of_device_id ltq_wdt_match[] = { | 286 | static 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 | }; |
228 | MODULE_DEVICE_TABLE(of, ltq_wdt_match); | 292 | MODULE_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 | |||
78 | static int divisor; | ||
76 | 79 | ||
77 | /* The count needed to achieve timeout_sec. */ | 80 | /* The count needed to achieve timeout_sec. */ |
78 | static unsigned int timeout_cnt; | 81 | static unsigned int timeout_cnt; |
@@ -84,7 +87,7 @@ static unsigned int max_timeout_sec; | |||
84 | static unsigned int timeout_sec; | 87 | static 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 */ |
87 | static int do_coundown; | 90 | static bool do_countdown; |
88 | static unsigned int countdown_reset; | 91 | static unsigned int countdown_reset; |
89 | static unsigned int per_cpu_countdown[NR_CPUS]; | 92 | static 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 | |||
95 | static int heartbeat = WD_TIMO; | 100 | static int heartbeat = WD_TIMO; |
96 | module_param(heartbeat, int, S_IRUGO); | 101 | module_param(heartbeat, int, 0444); |
97 | MODULE_PARM_DESC(heartbeat, | 102 | MODULE_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 | ||
101 | static bool nowayout = WATCHDOG_NOWAYOUT; | 106 | static bool nowayout = WATCHDOG_NOWAYOUT; |
102 | module_param(nowayout, bool, S_IRUGO); | 107 | module_param(nowayout, bool, 0444); |
103 | MODULE_PARM_DESC(nowayout, | 108 | MODULE_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 | ||
107 | static u32 nmi_stage1_insns[64] __initdata; | 112 | static int disable; |
108 | /* We need one branch and therefore one relocation per target label. */ | 113 | module_param(disable, int, 0444); |
109 | static struct uasm_label labels[5] __initdata; | 114 | MODULE_PARM_DESC(disable, |
110 | static struct uasm_reloc relocs[5] __initdata; | 115 | "Disable the watchdog entirely (default=0)"); |
111 | |||
112 | enum lable_id { | ||
113 | label_enter_bootloader = 1 | ||
114 | }; | ||
115 | 116 | ||
116 | /* Some CP0 registers */ | 117 | static 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 | ||
123 | void octeon_wdt_nmi_stage2(void); | 119 | void octeon_wdt_nmi_stage2(void); |
124 | 120 | ||
125 | static 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 | |||
223 | static int cpu2core(int cpu) | 121 | static 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 | ||
232 | static 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 | */ |
249 | static irqreturn_t octeon_wdt_poke_irq(int cpl, void *dev_id) | 138 | static 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 | |||
308 | static 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 | ||
376 | static int octeon_wdt_cpu_pre_down(unsigned int cpu) | 331 | static 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 | ||
478 | static int octeon_wdt_set_timeout(struct watchdog_device *wdog, | 461 | static 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, | |||
503 | static int octeon_wdt_start(struct watchdog_device *wdog) | 491 | static 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 | ||
510 | static int octeon_wdt_stop(struct watchdog_device *wdog) | 498 | static 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 | */ |
541 | static int __init octeon_wdt_init(void) | 529 | static 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: | |||
607 | static void __exit octeon_wdt_cleanup(void) | 599 | static 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 | ||
619 | MODULE_LICENSE("GPL"); | 615 | MODULE_LICENSE("GPL"); |
620 | MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); | 616 | MODULE_AUTHOR("Cavium Inc. <support@cavium.com>"); |
621 | MODULE_DESCRIPTION("Cavium Networks Octeon Watchdog driver."); | 617 | MODULE_DESCRIPTION("Cavium Inc. OCTEON Watchdog driver."); |
622 | module_init(octeon_wdt_init); | 618 | module_init(octeon_wdt_init); |
623 | module_exit(octeon_wdt_cleanup); | 619 | module_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) | ||
74 | 1: 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. */ |
61 | 1: b 1b | 87 | 2: 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 | |||
256 | extern unsigned int gic_present; | ||
257 | |||
258 | extern void gic_init(unsigned long gic_base_addr, | ||
259 | unsigned long gic_addrspace_size, unsigned int cpu_vec, | ||
260 | unsigned int irqbase); | ||
261 | extern u64 gic_read_count(void); | ||
262 | extern unsigned int gic_get_count_width(void); | ||
263 | extern u64 gic_read_compare(void); | ||
264 | extern void gic_write_compare(u64 cnt); | ||
265 | extern void gic_write_cpu_compare(u64 cnt, int cpu); | ||
266 | extern void gic_start_count(void); | ||
267 | extern void gic_stop_count(void); | ||
268 | extern int gic_get_c0_compare_int(void); | ||
269 | extern int gic_get_c0_perfcount_int(void); | ||
270 | extern int gic_get_c0_fdc_int(void); | ||
271 | extern int gic_get_usm_range(struct resource *gic_usm_res); | ||
272 | |||
273 | #else /* CONFIG_MIPS_GIC */ | ||
274 | |||
275 | #define gic_present 0 | ||
276 | |||
277 | static 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 | */ | ||
295 | extern unsigned gic_read_local_vp_id(void); | ||
296 | |||
297 | #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */ | ||