diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-19 13:02:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-19 13:02:26 -0400 |
commit | 07b75260ebc2c789724c594d7eaf0194fa47b3be (patch) | |
tree | d88b770bca479789e688d95e50aacd5d09b59b21 | |
parent | 0efacbbaee1e94e9942da0912f5b46ffd45a74bd (diff) | |
parent | 6e4ad1b413604b9130bdbe532aafdbd47ff5318e (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"This is the main pull request for MIPS for 4.7. Here's the summary of
the changes:
- ATH79: Support for DTB passuing using the UHI boot protocol
- ATH79: Remove support for builtin DTB.
- ATH79: Add zboot debug serial support.
- ATH79: Add initial support for Dragino MS14 (Dragine 2), Onion Omega
and DPT-Module.
- ATH79: Update devicetree clock support for AR9132 and AR9331.
- ATH79: Cleanup the DT code.
- ATH79: Support newer SOCs in ath79_ddr_ctrl_init.
- ATH79: Fix regression in PCI window initialization.
- BCM47xx: Move SPROM driver to drivers/firmware/
- BCM63xx: Enable partition parser in defconfig.
- BMIPS: BMIPS5000 has I cache filing from D cache
- BMIPS: BMIPS: Add cpu-feature-overrides.h
- BMIPS: Add Whirlwind support
- BMIPS: Adjust mips-hpt-frequency for BCM7435
- BMIPS: Remove maxcpus from BCM97435SVMB DTS
- BMIPS: Add missing 7038 L1 register cells to BCM7435
- BMIPS: Various tweaks to initialization code.
- BMIPS: Enable partition parser in defconfig.
- BMIPS: Cache tweaks.
- BMIPS: Add UART, I2C and SATA devices to DT.
- BMIPS: Add BCM6358 and BCM63268support
- BMIPS: Add device tree example for BCM6358.
- BMIPS: Improve Improve BCM6328 and BCM6368 device trees
- Lantiq: Add support for device tree file from boot loader
- Lantiq: Allow build with no built-in DT.
- Loongson 3: Reserve 32MB for RS780E integrated GPU.
- Loongson 3: Fix build error after ld-version.sh modification
- Loongson 3: Move chipset ACPI code from drivers to arch.
- Loongson 3: Speedup irq processing.
- Loongson 3: Add basic Loongson 3A support.
- Loongson 3: Set cache flush handlers to nop.
- Loongson 3: Invalidate special TLBs when needed.
- Loongson 3: Fast TLB refill handler.
- MT7620: Fallback strategy for invalid syscfg0.
- Netlogic: Fix CP0_EBASE redefinition warnings
- Octeon: Initialization fixes
- Octeon: Add DTS files for the D-Link DSR-1000N and EdgeRouter Lite
- Octeon: Enable add Octeon-drivers in cavium_octeon_defconfig
- Octeon: Correctly handle endian-swapped initramfs images.
- Octeon: Support CN73xx, CN75xx and CN78xx.
- Octeon: Remove dead code from cvmx-sysinfo.
- Octeon: Extend number of supported CPUs past 32.
- Octeon: Remove some code limiting NR_IRQS to 255.
- Octeon: Simplify octeon_irq_ciu_gpio_set_type.
- Octeon: Mark some functions __init in smp.c
- Octeon: Octeon: Add Octeon III CN7xxx interface detection
- PIC32: Add serial driver and bindings for it.
- PIC32: Add PIC32 deadman timer driver and bindings.
- PIC32: Add PIC32 clock timer driver and bindings.
- Pistachio: Determine SoC revision during boot
- Sibyte: Fix Kconfig dependencies of SIBYTE_BUS_WATCHER.
- Sibyte: Strip redundant comments from bcm1480_regs.h.
- Panic immediately if panic_on_oops is set.
- module: fix incorrect IS_ERR_VALUE macro usage.
- module: Make consistent use of pr_*
- Remove no longer needed work_on_cpu() call.
- Remove CONFIG_IPV6_PRIVACY from defconfigs.
- Fix registers of non-crashing CPUs in dumps.
- Handle MIPSisms in new vmcore_elf32_check_arch.
- Select CONFIG_HANDLE_DOMAIN_IRQ and make it work.
- Allow RIXI to be used on non-R2 or R6 cores.
- Reserve nosave data for hibernation
- Fix siginfo.h to use strict POSIX types.
- Don't unwind user mode with EVA.
- Fix watchpoint restoration
- Ptrace watchpoints for R6.
- Sync icache when it fills from dcache
- I6400 I-cache fills from dcache.
- Various MSA fixes.
- Cleanup MIPS_CPU_* definitions.
- Signal: Move generic copy_siginfo to signal.h
- Signal: Fix uapi include in exported asm/siginfo.h
- Timer fixes for sake of KVM.
- XPA TLB refill fixes.
- Treat perf counter feature
- Update John Crispin's email address
- Add PIC32 watchdog and bindings.
- Handle R10000 LL/SC bug in set_pte()
- cpufreq: Various fixes for Longson1.
- R6: Fix R2 emulation.
- mathemu: Cosmetic fix to ADDIUPC emulation, plenty of other small fixes
- ELF: ABI and FP fixes.
- Allow for relocatable kernel and use that to support KASLR.
- Fix CPC_BASE_ADDR mask
- Plenty fo smp-cps, CM, R6 and M6250 fixes.
- Make reset_control_ops const.
- Fix kernel command line handling of leading whitespace.
- Cleanups to cache handling.
- Add brcm, bcm6345-l1-intc device tree bindings.
- Use generic clkdev.h header
- Remove CLK_IS_ROOT usage.
- Misc small cleanups.
- CM: Fix compilation error when !MIPS_CM
- oprofile: Fix a preemption issue
- Detect DSP ASE v3 support:1"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (275 commits)
MIPS: pic32mzda: fix getting timer clock rate.
MIPS: ath79: fix regression in PCI window initialization
MIPS: ath79: make ath79_ddr_ctrl_init() compatible for newer SoCs
MIPS: Fix VZ probe gas errors with binutils <2.24
MIPS: perf: Fix I6400 event numbers
MIPS: DEC: Export `ioasic_ssr_lock' to modules
MIPS: MSA: Fix a link error on `_init_msa_upper' with older GCC
MIPS: CM: Fix compilation error when !MIPS_CM
MIPS: Fix genvdso error on rebuild
USB: ohci-jz4740: Remove obsolete driver
MIPS: JZ4740: Probe OHCI platform device via DT
MIPS: JZ4740: Qi LB60: Remove support for AVT2 variant
MIPS: pistachio: Determine SoC revision during boot
MIPS: BMIPS: Adjust mips-hpt-frequency for BCM7435
mips: mt7620: fallback to SDRAM when syscfg0 does not have a valid value for the memory type
MIPS: Prevent "restoration" of MSA context in non-MSA kernels
MIPS: cevt-r4k: Dynamically calculate min_delta_ns
MIPS: malta-time: Take seconds into account
MIPS: malta-time: Start GIC count before syncing to RTC
MIPS: Force CPUs to lose FP context during mode switches
...
358 files changed, 14005 insertions, 3399 deletions
diff --git a/Documentation/devicetree/bindings/clock/microchip,pic32.txt b/Documentation/devicetree/bindings/clock/microchip,pic32.txt new file mode 100644 index 000000000000..c93d88fdd858 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/microchip,pic32.txt | |||
@@ -0,0 +1,39 @@ | |||
1 | Microchip PIC32 Clock Controller Binding | ||
2 | ---------------------------------------- | ||
3 | Microchip clock controller is consists of few oscillators, PLL, multiplexer | ||
4 | and few divider modules. | ||
5 | |||
6 | This binding uses common clock bindings. | ||
7 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
8 | |||
9 | Required properties: | ||
10 | - compatible: shall be "microchip,pic32mzda-clk". | ||
11 | - reg: shall contain base address and length of clock registers. | ||
12 | - #clock-cells: shall be 1. | ||
13 | |||
14 | Optional properties: | ||
15 | - microchip,pic32mzda-sosc: shall be added only if platform has | ||
16 | secondary oscillator connected. | ||
17 | |||
18 | Example: | ||
19 | rootclk: clock-controller@1f801200 { | ||
20 | compatible = "microchip,pic32mzda-clk"; | ||
21 | reg = <0x1f801200 0x200>; | ||
22 | #clock-cells = <1>; | ||
23 | /* optional */ | ||
24 | microchip,pic32mzda-sosc; | ||
25 | }; | ||
26 | |||
27 | |||
28 | The clock consumer shall specify the desired clock-output of the clock | ||
29 | controller (as defined in [2]) by specifying output-id in its "clock" | ||
30 | phandle cell. | ||
31 | [2] include/dt-bindings/clock/microchip,pic32-clock.h | ||
32 | |||
33 | For example for UART2: | ||
34 | uart2: serial@2 { | ||
35 | compatible = "microchip,pic32mzda-uart"; | ||
36 | reg = <>; | ||
37 | interrupts = <>; | ||
38 | clocks = <&rootclk PB2CLK>; | ||
39 | }; | ||
diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l1-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l1-intc.txt new file mode 100644 index 000000000000..4040905388d9 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l1-intc.txt | |||
@@ -0,0 +1,57 @@ | |||
1 | Broadcom BCM6345-style Level 1 interrupt controller | ||
2 | |||
3 | This block is a first level interrupt controller that is typically connected | ||
4 | directly to one of the HW INT lines on each CPU. | ||
5 | |||
6 | Key elements of the hardware design include: | ||
7 | |||
8 | - 32, 64 or 128 incoming level IRQ lines | ||
9 | |||
10 | - Most onchip peripherals are wired directly to an L1 input | ||
11 | |||
12 | - A separate instance of the register set for each CPU, allowing individual | ||
13 | peripheral IRQs to be routed to any CPU | ||
14 | |||
15 | - Contains one or more enable/status word pairs per CPU | ||
16 | |||
17 | - No atomic set/clear operations | ||
18 | |||
19 | - No polarity/level/edge settings | ||
20 | |||
21 | - No FIFO or priority encoder logic; software is expected to read all | ||
22 | 2-4 status words to determine which IRQs are pending | ||
23 | |||
24 | Required properties: | ||
25 | |||
26 | - compatible: should be "brcm,bcm<soc>-l1-intc", "brcm,bcm6345-l1-intc" | ||
27 | - reg: specifies the base physical address and size of the registers; | ||
28 | the number of supported IRQs is inferred from the size argument | ||
29 | - interrupt-controller: identifies the node as an interrupt controller | ||
30 | - #interrupt-cells: specifies the number of cells needed to encode an interrupt | ||
31 | source, should be 1. | ||
32 | - interrupt-parent: specifies the phandle to the parent interrupt controller(s) | ||
33 | this one is cascaded from | ||
34 | - interrupts: specifies the interrupt line(s) in the interrupt-parent controller | ||
35 | node; valid values depend on the type of parent interrupt controller | ||
36 | |||
37 | If multiple reg ranges and interrupt-parent entries are present on an SMP | ||
38 | system, the driver will allow IRQ SMP affinity to be set up through the | ||
39 | /proc/irq/ interface. In the simplest possible configuration, only one | ||
40 | reg range and one interrupt-parent is needed. | ||
41 | |||
42 | The driver operates in native CPU endian by default, there is no support for | ||
43 | specifying an alternative endianness. | ||
44 | |||
45 | Example: | ||
46 | |||
47 | periph_intc: interrupt-controller@10000000 { | ||
48 | compatible = "brcm,bcm63168-l1-intc", "brcm,bcm6345-l1-intc"; | ||
49 | reg = <0x10000020 0x20>, | ||
50 | <0x10000040 0x20>; | ||
51 | |||
52 | interrupt-controller; | ||
53 | #interrupt-cells = <1>; | ||
54 | |||
55 | interrupt-parent = <&cpu_intc>; | ||
56 | interrupts = <2>, <3>; | ||
57 | }; | ||
diff --git a/Documentation/devicetree/bindings/mips/brcm/soc.txt b/Documentation/devicetree/bindings/mips/brcm/soc.txt index 7bab90cc4a7b..4a7e030e4f9b 100644 --- a/Documentation/devicetree/bindings/mips/brcm/soc.txt +++ b/Documentation/devicetree/bindings/mips/brcm/soc.txt | |||
@@ -4,7 +4,8 @@ Required properties: | |||
4 | 4 | ||
5 | - compatible: "brcm,bcm3384", "brcm,bcm33843" | 5 | - compatible: "brcm,bcm3384", "brcm,bcm33843" |
6 | "brcm,bcm3384-viper", "brcm,bcm33843-viper" | 6 | "brcm,bcm3384-viper", "brcm,bcm33843-viper" |
7 | "brcm,bcm6328", "brcm,bcm6368", | 7 | "brcm,bcm6328", "brcm,bcm6358", "brcm,bcm6368", |
8 | "brcm,bcm63168", "brcm,bcm63268", | ||
8 | "brcm,bcm7125", "brcm,bcm7346", "brcm,bcm7358", "brcm,bcm7360", | 9 | "brcm,bcm7125", "brcm,bcm7346", "brcm,bcm7358", "brcm,bcm7360", |
9 | "brcm,bcm7362", "brcm,bcm7420", "brcm,bcm7425" | 10 | "brcm,bcm7362", "brcm,bcm7420", "brcm,bcm7425" |
10 | 11 | ||
diff --git a/Documentation/devicetree/bindings/mips/cavium/ciu3.txt b/Documentation/devicetree/bindings/mips/cavium/ciu3.txt new file mode 100644 index 000000000000..616862ad2b71 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/cavium/ciu3.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | * Central Interrupt Unit v3 | ||
2 | |||
3 | Properties: | ||
4 | - compatible: "cavium,octeon-7890-ciu3" | ||
5 | |||
6 | Compatibility with 78XX and 73XX SOCs. | ||
7 | |||
8 | - interrupt-controller: This is an interrupt controller. | ||
9 | |||
10 | - reg: The base address of the CIU's register bank. | ||
11 | |||
12 | - #interrupt-cells: Must be <2>. The first cell is source number. | ||
13 | The second cell indicates the triggering semantics, and may have a | ||
14 | value of either 4 for level semantics, or 1 for edge semantics. | ||
15 | |||
16 | Example: | ||
17 | interrupt-controller@1010000000000 { | ||
18 | compatible = "cavium,octeon-7890-ciu3"; | ||
19 | interrupt-controller; | ||
20 | /* Interrupts are specified by two parts: | ||
21 | * 1) Source number (20 significant bits) | ||
22 | * 2) Trigger type: (4 == level, 1 == edge) | ||
23 | */ | ||
24 | #address-cells = <0>; | ||
25 | #interrupt-cells = <2>; | ||
26 | reg = <0x10100 0x00000000 0x0 0xb0000000>; | ||
27 | }; | ||
diff --git a/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt b/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt new file mode 100644 index 000000000000..65b38bf60ae0 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/microchip,pic32-uart.txt | |||
@@ -0,0 +1,29 @@ | |||
1 | * Microchip Universal Asynchronous Receiver Transmitter (UART) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "microchip,pic32mzda-uart" | ||
5 | - reg: Should contain registers location and length | ||
6 | - interrupts: Should contain interrupt | ||
7 | - clocks: Phandle to the clock. | ||
8 | See: Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
9 | - pinctrl-names: A pinctrl state names "default" must be defined. | ||
10 | - pinctrl-0: Phandle referencing pin configuration of the UART peripheral. | ||
11 | See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt | ||
12 | |||
13 | Optional properties: | ||
14 | - cts-gpios: CTS pin for UART | ||
15 | |||
16 | Example: | ||
17 | uart1: serial@1f822000 { | ||
18 | compatible = "microchip,pic32mzda-uart"; | ||
19 | reg = <0x1f822000 0x50>; | ||
20 | interrupts = <112 IRQ_TYPE_LEVEL_HIGH>, | ||
21 | <113 IRQ_TYPE_LEVEL_HIGH>, | ||
22 | <114 IRQ_TYPE_LEVEL_HIGH>; | ||
23 | clocks = <&PBCLK2>; | ||
24 | pinctrl-names = "default"; | ||
25 | pinctrl-0 = <&pinctrl_uart1 | ||
26 | &pinctrl_uart1_cts | ||
27 | &pinctrl_uart1_rts>; | ||
28 | cts-gpios = <&gpio1 15 0>; | ||
29 | }; | ||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 021bbe7866e0..316412dc7913 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -72,6 +72,8 @@ digilent Diglent, Inc. | |||
72 | dlg Dialog Semiconductor | 72 | dlg Dialog Semiconductor |
73 | dlink D-Link Corporation | 73 | dlink D-Link Corporation |
74 | dmo Data Modul AG | 74 | dmo Data Modul AG |
75 | dptechnics DPTechnics | ||
76 | dragino Dragino Technology Co., Limited | ||
75 | ea Embedded Artists AB | 77 | ea Embedded Artists AB |
76 | ebv EBV Elektronik | 78 | ebv EBV Elektronik |
77 | edt Emerging Display Technologies | 79 | edt Emerging Display Technologies |
@@ -176,6 +178,7 @@ nvidia NVIDIA | |||
176 | nxp NXP Semiconductors | 178 | nxp NXP Semiconductors |
177 | okaya Okaya Electric America, Inc. | 179 | okaya Okaya Electric America, Inc. |
178 | olimex OLIMEX Ltd. | 180 | olimex OLIMEX Ltd. |
181 | onion Onion Corporation | ||
179 | onnn ON Semiconductor Corp. | 182 | onnn ON Semiconductor Corp. |
180 | opencores OpenCores.org | 183 | opencores OpenCores.org |
181 | option Option NV | 184 | option Option NV |
diff --git a/Documentation/devicetree/bindings/watchdog/microchip,pic32-dmt.txt b/Documentation/devicetree/bindings/watchdog/microchip,pic32-dmt.txt new file mode 100644 index 000000000000..852f694f3177 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/microchip,pic32-dmt.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | * Microchip PIC32 Deadman Timer | ||
2 | |||
3 | The deadman timer is used to reset the processor in the event of a software | ||
4 | malfunction. It is a free-running instruction fetch timer, which is clocked | ||
5 | whenever an instruction fetch occurs until a count match occurs. | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: must be "microchip,pic32mzda-dmt". | ||
9 | - reg: physical base address of the controller and length of memory mapped | ||
10 | region. | ||
11 | - clocks: phandle of parent clock (should be &PBCLK7). | ||
12 | |||
13 | Example: | ||
14 | |||
15 | watchdog@1f800a00 { | ||
16 | compatible = "microchip,pic32mzda-dmt"; | ||
17 | reg = <0x1f800a00 0x80>; | ||
18 | clocks = <&PBCLK7>; | ||
19 | }; | ||
diff --git a/Documentation/devicetree/bindings/watchdog/microchip,pic32-wdt.txt b/Documentation/devicetree/bindings/watchdog/microchip,pic32-wdt.txt new file mode 100644 index 000000000000..d1401030e75c --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/microchip,pic32-wdt.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * Microchip PIC32 Watchdog Timer | ||
2 | |||
3 | When enabled, the watchdog peripheral can be used to reset the device if the | ||
4 | WDT is not cleared periodically in software. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: must be "microchip,pic32mzda-wdt". | ||
8 | - reg: physical base address of the controller and length of memory mapped | ||
9 | region. | ||
10 | - clocks: phandle of source clk. should be <&LPRC> clk. | ||
11 | |||
12 | Example: | ||
13 | |||
14 | watchdog@1f800800 { | ||
15 | compatible = "microchip,pic32mzda-wdt"; | ||
16 | reg = <0x1f800800 0x200>; | ||
17 | clocks = <&LPRC>; | ||
18 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 3f14e1dffa6a..ef8a56e04af6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6491,7 +6491,7 @@ F: net/l3mdev | |||
6491 | F: include/net/l3mdev.h | 6491 | F: include/net/l3mdev.h |
6492 | 6492 | ||
6493 | LANTIQ MIPS ARCHITECTURE | 6493 | LANTIQ MIPS ARCHITECTURE |
6494 | M: John Crispin <blogic@openwrt.org> | 6494 | M: John Crispin <john@phrozen.org> |
6495 | L: linux-mips@linux-mips.org | 6495 | L: linux-mips@linux-mips.org |
6496 | S: Maintained | 6496 | S: Maintained |
6497 | F: arch/mips/lantiq | 6497 | F: arch/mips/lantiq |
@@ -7332,6 +7332,15 @@ S: Supported | |||
7332 | F: Documentation/mips/ | 7332 | F: Documentation/mips/ |
7333 | F: arch/mips/ | 7333 | F: arch/mips/ |
7334 | 7334 | ||
7335 | MIPS/LOONGSON1 ARCHITECTURE | ||
7336 | M: Keguang Zhang <keguang.zhang@gmail.com> | ||
7337 | L: linux-mips@linux-mips.org | ||
7338 | S: Maintained | ||
7339 | F: arch/mips/loongson32/ | ||
7340 | F: arch/mips/include/asm/mach-loongson32/ | ||
7341 | F: drivers/*/*loongson1* | ||
7342 | F: drivers/*/*/*loongson1* | ||
7343 | |||
7335 | MIROSOUND PCM20 FM RADIO RECEIVER DRIVER | 7344 | MIROSOUND PCM20 FM RADIO RECEIVER DRIVER |
7336 | M: Hans Verkuil <hverkuil@xs4all.nl> | 7345 | M: Hans Verkuil <hverkuil@xs4all.nl> |
7337 | L: linux-media@vger.kernel.org | 7346 | L: linux-media@vger.kernel.org |
@@ -9251,7 +9260,7 @@ S: Maintained | |||
9251 | F: drivers/video/fbdev/aty/aty128fb.c | 9260 | F: drivers/video/fbdev/aty/aty128fb.c |
9252 | 9261 | ||
9253 | RALINK MIPS ARCHITECTURE | 9262 | RALINK MIPS ARCHITECTURE |
9254 | M: John Crispin <blogic@openwrt.org> | 9263 | M: John Crispin <john@phrozen.org> |
9255 | L: linux-mips@linux-mips.org | 9264 | L: linux-mips@linux-mips.org |
9256 | S: Maintained | 9265 | S: Maintained |
9257 | F: arch/mips/ralink | 9266 | F: arch/mips/ralink |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d2ac1174ee17..5663f411c225 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -62,6 +62,7 @@ config MIPS | |||
62 | select HAVE_IRQ_TIME_ACCOUNTING | 62 | select HAVE_IRQ_TIME_ACCOUNTING |
63 | select GENERIC_TIME_VSYSCALL | 63 | select GENERIC_TIME_VSYSCALL |
64 | select ARCH_CLOCKSOURCE_DATA | 64 | select ARCH_CLOCKSOURCE_DATA |
65 | select HANDLE_DOMAIN_IRQ | ||
65 | 66 | ||
66 | menu "Machine selection" | 67 | menu "Machine selection" |
67 | 68 | ||
@@ -137,7 +138,7 @@ config ATH79 | |||
137 | select SYS_SUPPORTS_32BIT_KERNEL | 138 | select SYS_SUPPORTS_32BIT_KERNEL |
138 | select SYS_SUPPORTS_BIG_ENDIAN | 139 | select SYS_SUPPORTS_BIG_ENDIAN |
139 | select SYS_SUPPORTS_MIPS16 | 140 | select SYS_SUPPORTS_MIPS16 |
140 | select SYS_SUPPORTS_ZBOOT | 141 | select SYS_SUPPORTS_ZBOOT_UART_PROM |
141 | select USE_OF | 142 | select USE_OF |
142 | help | 143 | help |
143 | Support for the Atheros AR71XX/AR724X/AR913X SoCs. | 144 | Support for the Atheros AR71XX/AR724X/AR913X SoCs. |
@@ -194,6 +195,7 @@ config BCM47XX | |||
194 | select GPIOLIB | 195 | select GPIOLIB |
195 | select LEDS_GPIO_REGISTER | 196 | select LEDS_GPIO_REGISTER |
196 | select BCM47XX_NVRAM | 197 | select BCM47XX_NVRAM |
198 | select BCM47XX_SPROM | ||
197 | help | 199 | help |
198 | Support for BCM47XX based boards | 200 | Support for BCM47XX based boards |
199 | 201 | ||
@@ -471,6 +473,7 @@ config MIPS_MALTA | |||
471 | select SYS_SUPPORTS_MULTITHREADING | 473 | select SYS_SUPPORTS_MULTITHREADING |
472 | select SYS_SUPPORTS_SMARTMIPS | 474 | select SYS_SUPPORTS_SMARTMIPS |
473 | select SYS_SUPPORTS_ZBOOT | 475 | select SYS_SUPPORTS_ZBOOT |
476 | select SYS_SUPPORTS_RELOCATABLE | ||
474 | select USE_OF | 477 | select USE_OF |
475 | select ZONE_DMA32 if 64BIT | 478 | select ZONE_DMA32 if 64BIT |
476 | select BUILTIN_DTB | 479 | select BUILTIN_DTB |
@@ -505,6 +508,7 @@ config MIPS_SEAD3 | |||
505 | select MIPS_MSC | 508 | select MIPS_MSC |
506 | select SYS_HAS_CPU_MIPS32_R1 | 509 | select SYS_HAS_CPU_MIPS32_R1 |
507 | select SYS_HAS_CPU_MIPS32_R2 | 510 | select SYS_HAS_CPU_MIPS32_R2 |
511 | select SYS_HAS_CPU_MIPS32_R6 | ||
508 | select SYS_HAS_CPU_MIPS64_R1 | 512 | select SYS_HAS_CPU_MIPS64_R1 |
509 | select SYS_HAS_EARLY_PRINTK | 513 | select SYS_HAS_EARLY_PRINTK |
510 | select SYS_SUPPORTS_32BIT_KERNEL | 514 | select SYS_SUPPORTS_32BIT_KERNEL |
@@ -514,6 +518,7 @@ config MIPS_SEAD3 | |||
514 | select SYS_SUPPORTS_SMARTMIPS | 518 | select SYS_SUPPORTS_SMARTMIPS |
515 | select SYS_SUPPORTS_MICROMIPS | 519 | select SYS_SUPPORTS_MICROMIPS |
516 | select SYS_SUPPORTS_MIPS16 | 520 | select SYS_SUPPORTS_MIPS16 |
521 | select SYS_SUPPORTS_RELOCATABLE | ||
517 | select USB_EHCI_BIG_ENDIAN_DESC | 522 | select USB_EHCI_BIG_ENDIAN_DESC |
518 | select USB_EHCI_BIG_ENDIAN_MMIO | 523 | select USB_EHCI_BIG_ENDIAN_MMIO |
519 | select USE_OF | 524 | select USE_OF |
@@ -1153,6 +1158,13 @@ config ISA_DMA_API | |||
1153 | config HOLES_IN_ZONE | 1158 | config HOLES_IN_ZONE |
1154 | bool | 1159 | bool |
1155 | 1160 | ||
1161 | config SYS_SUPPORTS_RELOCATABLE | ||
1162 | bool | ||
1163 | help | ||
1164 | Selected if the platform supports relocating the kernel. | ||
1165 | The platform must provide plat_get_fdt() if it selects CONFIG_USE_OF | ||
1166 | to allow access to command line and entropy sources. | ||
1167 | |||
1156 | # | 1168 | # |
1157 | # Endianness selection. Sufficiently obscure so many users don't know what to | 1169 | # Endianness selection. Sufficiently obscure so many users don't know what to |
1158 | # answer,so we try hard to limit the available choices. Also the use of a | 1170 | # answer,so we try hard to limit the available choices. Also the use of a |
@@ -1340,11 +1352,30 @@ config CPU_LOONGSON3 | |||
1340 | select CPU_SUPPORTS_HUGEPAGES | 1352 | select CPU_SUPPORTS_HUGEPAGES |
1341 | select WEAK_ORDERING | 1353 | select WEAK_ORDERING |
1342 | select WEAK_REORDERING_BEYOND_LLSC | 1354 | select WEAK_REORDERING_BEYOND_LLSC |
1355 | select MIPS_PGD_C0_CONTEXT | ||
1343 | select GPIOLIB | 1356 | select GPIOLIB |
1344 | help | 1357 | help |
1345 | The Loongson 3 processor implements the MIPS64R2 instruction | 1358 | The Loongson 3 processor implements the MIPS64R2 instruction |
1346 | set with many extensions. | 1359 | set with many extensions. |
1347 | 1360 | ||
1361 | config LOONGSON3_ENHANCEMENT | ||
1362 | bool "New Loongson 3 CPU Enhancements" | ||
1363 | default n | ||
1364 | select CPU_MIPSR2 | ||
1365 | select CPU_HAS_PREFETCH | ||
1366 | depends on CPU_LOONGSON3 | ||
1367 | help | ||
1368 | New Loongson 3 CPU (since Loongson-3A R2, as opposed to Loongson-3A | ||
1369 | R1, Loongson-3B R1 and Loongson-3B R2) has many enhancements, such as | ||
1370 | FTLB, L1-VCache, EI/DI/Wait/Prefetch instruction, DSP/DSPv2 ASE, User | ||
1371 | Local register, Read-Inhibit/Execute-Inhibit, SFB (Store Fill Buffer), | ||
1372 | Fast TLB refill support, etc. | ||
1373 | |||
1374 | This option enable those enhancements which are not probed at run | ||
1375 | time. If you want a generic kernel to run on all Loongson 3 machines, | ||
1376 | please say 'N' here. If you want a high-performance kernel to run on | ||
1377 | new Loongson 3 machines only, please say 'Y' here. | ||
1378 | |||
1348 | config CPU_LOONGSON2E | 1379 | config CPU_LOONGSON2E |
1349 | bool "Loongson 2E" | 1380 | bool "Loongson 2E" |
1350 | depends on SYS_HAS_CPU_LOONGSON2E | 1381 | depends on SYS_HAS_CPU_LOONGSON2E |
@@ -1373,6 +1404,8 @@ config CPU_LOONGSON1B | |||
1373 | bool "Loongson 1B" | 1404 | bool "Loongson 1B" |
1374 | depends on SYS_HAS_CPU_LOONGSON1B | 1405 | depends on SYS_HAS_CPU_LOONGSON1B |
1375 | select CPU_LOONGSON1 | 1406 | select CPU_LOONGSON1 |
1407 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
1408 | select LEDS_GPIO_REGISTER | ||
1376 | help | 1409 | help |
1377 | The Loongson 1B is a 32-bit SoC, which implements the MIPS32 | 1410 | The Loongson 1B is a 32-bit SoC, which implements the MIPS32 |
1378 | release 2 instruction set. | 1411 | release 2 instruction set. |
@@ -1671,6 +1704,7 @@ config CPU_XLP | |||
1671 | select CPU_HAS_PREFETCH | 1704 | select CPU_HAS_PREFETCH |
1672 | select CPU_MIPSR2 | 1705 | select CPU_MIPSR2 |
1673 | select CPU_SUPPORTS_HUGEPAGES | 1706 | select CPU_SUPPORTS_HUGEPAGES |
1707 | select MIPS_ASID_BITS_VARIABLE | ||
1674 | help | 1708 | help |
1675 | Netlogic Microsystems XLP processors. | 1709 | Netlogic Microsystems XLP processors. |
1676 | endchoice | 1710 | endchoice |
@@ -1796,6 +1830,7 @@ config CPU_BMIPS4380 | |||
1796 | select MIPS_L1_CACHE_SHIFT_6 | 1830 | select MIPS_L1_CACHE_SHIFT_6 |
1797 | select SYS_SUPPORTS_SMP | 1831 | select SYS_SUPPORTS_SMP |
1798 | select SYS_SUPPORTS_HOTPLUG_CPU | 1832 | select SYS_SUPPORTS_HOTPLUG_CPU |
1833 | select CPU_HAS_RIXI | ||
1799 | 1834 | ||
1800 | config CPU_BMIPS5000 | 1835 | config CPU_BMIPS5000 |
1801 | bool | 1836 | bool |
@@ -1803,10 +1838,12 @@ config CPU_BMIPS5000 | |||
1803 | select MIPS_L1_CACHE_SHIFT_7 | 1838 | select MIPS_L1_CACHE_SHIFT_7 |
1804 | select SYS_SUPPORTS_SMP | 1839 | select SYS_SUPPORTS_SMP |
1805 | select SYS_SUPPORTS_HOTPLUG_CPU | 1840 | select SYS_SUPPORTS_HOTPLUG_CPU |
1841 | select CPU_HAS_RIXI | ||
1806 | 1842 | ||
1807 | config SYS_HAS_CPU_LOONGSON3 | 1843 | config SYS_HAS_CPU_LOONGSON3 |
1808 | bool | 1844 | bool |
1809 | select CPU_SUPPORTS_CPUFREQ | 1845 | select CPU_SUPPORTS_CPUFREQ |
1846 | select CPU_HAS_RIXI | ||
1810 | 1847 | ||
1811 | config SYS_HAS_CPU_LOONGSON2E | 1848 | config SYS_HAS_CPU_LOONGSON2E |
1812 | bool | 1849 | bool |
@@ -1959,11 +1996,15 @@ config CPU_MIPSR1 | |||
1959 | config CPU_MIPSR2 | 1996 | config CPU_MIPSR2 |
1960 | bool | 1997 | bool |
1961 | default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON | 1998 | default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON |
1999 | select CPU_HAS_RIXI | ||
1962 | select MIPS_SPRAM | 2000 | select MIPS_SPRAM |
1963 | 2001 | ||
1964 | config CPU_MIPSR6 | 2002 | config CPU_MIPSR6 |
1965 | bool | 2003 | bool |
1966 | default y if CPU_MIPS32_R6 || CPU_MIPS64_R6 | 2004 | default y if CPU_MIPS32_R6 || CPU_MIPS64_R6 |
2005 | select CPU_HAS_RIXI | ||
2006 | select HAVE_ARCH_BITREVERSE | ||
2007 | select MIPS_ASID_BITS_VARIABLE | ||
1967 | select MIPS_SPRAM | 2008 | select MIPS_SPRAM |
1968 | 2009 | ||
1969 | config EVA | 2010 | config EVA |
@@ -1997,7 +2038,7 @@ config MIPS_PGD_C0_CONTEXT | |||
1997 | # | 2038 | # |
1998 | config HARDWARE_WATCHPOINTS | 2039 | config HARDWARE_WATCHPOINTS |
1999 | bool | 2040 | bool |
2000 | default y if CPU_MIPSR1 || CPU_MIPSR2 | 2041 | default y if CPU_MIPSR1 || CPU_MIPSR2 || CPU_MIPSR6 |
2001 | 2042 | ||
2002 | menu "Kernel type" | 2043 | menu "Kernel type" |
2003 | 2044 | ||
@@ -2040,6 +2081,16 @@ config KVM_GUEST_TIMER_FREQ | |||
2040 | emulation when determining guest CPU Frequency. Instead, the guest's | 2081 | emulation when determining guest CPU Frequency. Instead, the guest's |
2041 | timer frequency is specified directly. | 2082 | timer frequency is specified directly. |
2042 | 2083 | ||
2084 | config MIPS_VA_BITS_48 | ||
2085 | bool "48 bits virtual memory" | ||
2086 | depends on 64BIT | ||
2087 | help | ||
2088 | Support a maximum at least 48 bits of application virtual memory. | ||
2089 | Default is 40 bits or less, depending on the CPU. | ||
2090 | This option result in a small memory overhead for page tables. | ||
2091 | This option is only supported with 16k and 64k page sizes. | ||
2092 | If unsure, say N. | ||
2093 | |||
2043 | choice | 2094 | choice |
2044 | prompt "Kernel page size" | 2095 | prompt "Kernel page size" |
2045 | default PAGE_SIZE_4KB | 2096 | default PAGE_SIZE_4KB |
@@ -2047,6 +2098,7 @@ choice | |||
2047 | config PAGE_SIZE_4KB | 2098 | config PAGE_SIZE_4KB |
2048 | bool "4kB" | 2099 | bool "4kB" |
2049 | depends on !CPU_LOONGSON2 && !CPU_LOONGSON3 | 2100 | depends on !CPU_LOONGSON2 && !CPU_LOONGSON3 |
2101 | depends on !MIPS_VA_BITS_48 | ||
2050 | help | 2102 | help |
2051 | This option select the standard 4kB Linux page size. On some | 2103 | This option select the standard 4kB Linux page size. On some |
2052 | R3000-family processors this is the only available page size. Using | 2104 | R3000-family processors this is the only available page size. Using |
@@ -2056,6 +2108,7 @@ config PAGE_SIZE_4KB | |||
2056 | config PAGE_SIZE_8KB | 2108 | config PAGE_SIZE_8KB |
2057 | bool "8kB" | 2109 | bool "8kB" |
2058 | depends on CPU_R8000 || CPU_CAVIUM_OCTEON | 2110 | depends on CPU_R8000 || CPU_CAVIUM_OCTEON |
2111 | depends on !MIPS_VA_BITS_48 | ||
2059 | help | 2112 | help |
2060 | Using 8kB page size will result in higher performance kernel at | 2113 | Using 8kB page size will result in higher performance kernel at |
2061 | the price of higher memory consumption. This option is available | 2114 | the price of higher memory consumption. This option is available |
@@ -2074,6 +2127,7 @@ config PAGE_SIZE_16KB | |||
2074 | config PAGE_SIZE_32KB | 2127 | config PAGE_SIZE_32KB |
2075 | bool "32kB" | 2128 | bool "32kB" |
2076 | depends on CPU_CAVIUM_OCTEON | 2129 | depends on CPU_CAVIUM_OCTEON |
2130 | depends on !MIPS_VA_BITS_48 | ||
2077 | help | 2131 | help |
2078 | Using 32kB page size will result in higher performance kernel at | 2132 | Using 32kB page size will result in higher performance kernel at |
2079 | the price of higher memory consumption. This option is available | 2133 | the price of higher memory consumption. This option is available |
@@ -2278,7 +2332,7 @@ config MIPS_CMP | |||
2278 | 2332 | ||
2279 | config MIPS_CPS | 2333 | config MIPS_CPS |
2280 | bool "MIPS Coherent Processing System support" | 2334 | bool "MIPS Coherent Processing System support" |
2281 | depends on SYS_SUPPORTS_MIPS_CPS && !CPU_MIPSR6 | 2335 | depends on SYS_SUPPORTS_MIPS_CPS |
2282 | select MIPS_CM | 2336 | select MIPS_CM |
2283 | select MIPS_CPC | 2337 | select MIPS_CPC |
2284 | select MIPS_CPS_PM if HOTPLUG_CPU | 2338 | select MIPS_CPS_PM if HOTPLUG_CPU |
@@ -2369,6 +2423,9 @@ config CPU_HAS_WB | |||
2369 | config XKS01 | 2423 | config XKS01 |
2370 | bool | 2424 | bool |
2371 | 2425 | ||
2426 | config CPU_HAS_RIXI | ||
2427 | bool | ||
2428 | |||
2372 | # | 2429 | # |
2373 | # Vectored interrupt mode is an R2 feature | 2430 | # Vectored interrupt mode is an R2 feature |
2374 | # | 2431 | # |
@@ -2399,6 +2456,21 @@ config CPU_R4000_WORKAROUNDS | |||
2399 | config CPU_R4400_WORKAROUNDS | 2456 | config CPU_R4400_WORKAROUNDS |
2400 | bool | 2457 | bool |
2401 | 2458 | ||
2459 | config MIPS_ASID_SHIFT | ||
2460 | int | ||
2461 | default 6 if CPU_R3000 || CPU_TX39XX | ||
2462 | default 4 if CPU_R8000 | ||
2463 | default 0 | ||
2464 | |||
2465 | config MIPS_ASID_BITS | ||
2466 | int | ||
2467 | default 0 if MIPS_ASID_BITS_VARIABLE | ||
2468 | default 6 if CPU_R3000 || CPU_TX39XX | ||
2469 | default 8 | ||
2470 | |||
2471 | config MIPS_ASID_BITS_VARIABLE | ||
2472 | bool | ||
2473 | |||
2402 | # | 2474 | # |
2403 | # - Highmem only makes sense for the 32-bit kernel. | 2475 | # - Highmem only makes sense for the 32-bit kernel. |
2404 | # - The current highmem code will only work properly on physically indexed | 2476 | # - The current highmem code will only work properly on physically indexed |
@@ -2468,6 +2540,61 @@ config NUMA | |||
2468 | config SYS_SUPPORTS_NUMA | 2540 | config SYS_SUPPORTS_NUMA |
2469 | bool | 2541 | bool |
2470 | 2542 | ||
2543 | config RELOCATABLE | ||
2544 | bool "Relocatable kernel" | ||
2545 | depends on SYS_SUPPORTS_RELOCATABLE && (CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_MIPS32_R6 || CPU_MIPS64_R6) | ||
2546 | help | ||
2547 | This builds a kernel image that retains relocation information | ||
2548 | so it can be loaded someplace besides the default 1MB. | ||
2549 | The relocations make the kernel binary about 15% larger, | ||
2550 | but are discarded at runtime | ||
2551 | |||
2552 | config RELOCATION_TABLE_SIZE | ||
2553 | hex "Relocation table size" | ||
2554 | depends on RELOCATABLE | ||
2555 | range 0x0 0x01000000 | ||
2556 | default "0x00100000" | ||
2557 | ---help--- | ||
2558 | A table of relocation data will be appended to the kernel binary | ||
2559 | and parsed at boot to fix up the relocated kernel. | ||
2560 | |||
2561 | This option allows the amount of space reserved for the table to be | ||
2562 | adjusted, although the default of 1Mb should be ok in most cases. | ||
2563 | |||
2564 | The build will fail and a valid size suggested if this is too small. | ||
2565 | |||
2566 | If unsure, leave at the default value. | ||
2567 | |||
2568 | config RANDOMIZE_BASE | ||
2569 | bool "Randomize the address of the kernel image" | ||
2570 | depends on RELOCATABLE | ||
2571 | ---help--- | ||
2572 | Randomizes the physical and virtual address at which the | ||
2573 | kernel image is loaded, as a security feature that | ||
2574 | deters exploit attempts relying on knowledge of the location | ||
2575 | of kernel internals. | ||
2576 | |||
2577 | Entropy is generated using any coprocessor 0 registers available. | ||
2578 | |||
2579 | The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET. | ||
2580 | |||
2581 | If unsure, say N. | ||
2582 | |||
2583 | config RANDOMIZE_BASE_MAX_OFFSET | ||
2584 | hex "Maximum kASLR offset" if EXPERT | ||
2585 | depends on RANDOMIZE_BASE | ||
2586 | range 0x0 0x40000000 if EVA || 64BIT | ||
2587 | range 0x0 0x08000000 | ||
2588 | default "0x01000000" | ||
2589 | ---help--- | ||
2590 | When kASLR is active, this provides the maximum offset that will | ||
2591 | be applied to the kernel image. It should be set according to the | ||
2592 | amount of physical RAM available in the target system minus | ||
2593 | PHYSICAL_START and must be a power of 2. | ||
2594 | |||
2595 | This is limited by the size of KSEG0, 256Mb on 32-bit or 1Gb with | ||
2596 | EVA or 64-bit. The default is 16Mb. | ||
2597 | |||
2471 | config NODES_SHIFT | 2598 | config NODES_SHIFT |
2472 | int | 2599 | int |
2473 | default "6" | 2600 | default "6" |
@@ -2475,7 +2602,7 @@ config NODES_SHIFT | |||
2475 | 2602 | ||
2476 | config HW_PERF_EVENTS | 2603 | config HW_PERF_EVENTS |
2477 | bool "Enable hardware performance counter support for perf events" | 2604 | bool "Enable hardware performance counter support for perf events" |
2478 | depends on PERF_EVENTS && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON3) | 2605 | depends on PERF_EVENTS && !OPROFILE && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON3) |
2479 | default y | 2606 | default y |
2480 | help | 2607 | help |
2481 | Enable hardware performance counter support for perf events. If | 2608 | Enable hardware performance counter support for perf events. If |
@@ -2808,6 +2935,10 @@ choice | |||
2808 | 2935 | ||
2809 | config MIPS_CMDLINE_FROM_BOOTLOADER | 2936 | config MIPS_CMDLINE_FROM_BOOTLOADER |
2810 | bool "Bootloader kernel arguments if available" | 2937 | bool "Bootloader kernel arguments if available" |
2938 | |||
2939 | config MIPS_CMDLINE_BUILTIN_EXTEND | ||
2940 | depends on CMDLINE_BOOL | ||
2941 | bool "Extend builtin kernel arguments with bootloader arguments" | ||
2811 | endchoice | 2942 | endchoice |
2812 | 2943 | ||
2813 | endmenu | 2944 | endmenu |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index e78d60dbdffd..efd7a9dc93c4 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -12,6 +12,9 @@ | |||
12 | # for "archclean" cleaning up for this architecture. | 12 | # for "archclean" cleaning up for this architecture. |
13 | # | 13 | # |
14 | 14 | ||
15 | archscripts: scripts_basic | ||
16 | $(Q)$(MAKE) $(build)=arch/mips/boot/tools relocs | ||
17 | |||
15 | KBUILD_DEFCONFIG := ip22_defconfig | 18 | KBUILD_DEFCONFIG := ip22_defconfig |
16 | 19 | ||
17 | # | 20 | # |
@@ -93,6 +96,10 @@ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib | |||
93 | KBUILD_AFLAGS_MODULE += -mlong-calls | 96 | KBUILD_AFLAGS_MODULE += -mlong-calls |
94 | KBUILD_CFLAGS_MODULE += -mlong-calls | 97 | KBUILD_CFLAGS_MODULE += -mlong-calls |
95 | 98 | ||
99 | ifeq ($(CONFIG_RELOCATABLE),y) | ||
100 | LDFLAGS_vmlinux += --emit-relocs | ||
101 | endif | ||
102 | |||
96 | # | 103 | # |
97 | # pass -msoft-float to GAS if it supports it. However on newer binutils | 104 | # pass -msoft-float to GAS if it supports it. However on newer binutils |
98 | # (specifically newer than 2.24.51.20140728) we then also need to explicitly | 105 | # (specifically newer than 2.24.51.20140728) we then also need to explicitly |
@@ -193,6 +200,8 @@ ifeq ($(CONFIG_CPU_HAS_MSA),y) | |||
193 | toolchain-msa := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$(comma)-mmsa) | 200 | toolchain-msa := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$(comma)-mmsa) |
194 | cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA | 201 | cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA |
195 | endif | 202 | endif |
203 | toolchain-virt := $(call cc-option-yn,$(mips-cflags) -mvirt) | ||
204 | cflags-$(toolchain-virt) += -DTOOLCHAIN_SUPPORTS_VIRT | ||
196 | 205 | ||
197 | cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER) += -mcompact-branches=never | 206 | cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER) += -mcompact-branches=never |
198 | cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL) += -mcompact-branches=optimal | 207 | cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL) += -mcompact-branches=optimal |
@@ -310,6 +319,10 @@ rom.bin rom.sw: vmlinux | |||
310 | $(bootvars-y) $@ | 319 | $(bootvars-y) $@ |
311 | endif | 320 | endif |
312 | 321 | ||
322 | CMD_RELOCS = arch/mips/boot/tools/relocs | ||
323 | quiet_cmd_relocs = RELOCS $< | ||
324 | cmd_relocs = $(CMD_RELOCS) $< | ||
325 | |||
313 | # | 326 | # |
314 | # Some machines like the Indy need 32-bit ELF binaries for booting purposes. | 327 | # Some machines like the Indy need 32-bit ELF binaries for booting purposes. |
315 | # Other need ECOFF, so we build a 32-bit ELF binary for them which we then | 328 | # Other need ECOFF, so we build a 32-bit ELF binary for them which we then |
@@ -318,6 +331,11 @@ endif | |||
318 | quiet_cmd_32 = OBJCOPY $@ | 331 | quiet_cmd_32 = OBJCOPY $@ |
319 | cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@ | 332 | cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@ |
320 | vmlinux.32: vmlinux | 333 | vmlinux.32: vmlinux |
334 | ifeq ($(CONFIG_RELOCATABLE)$(CONFIG_64BIT),yy) | ||
335 | # Currently, objcopy fails to handle the relocations in the elf64 | ||
336 | # So the relocs tool must be run here to remove them first | ||
337 | $(call cmd,relocs) | ||
338 | endif | ||
321 | $(call cmd,32) | 339 | $(call cmd,32) |
322 | 340 | ||
323 | # | 341 | # |
@@ -333,6 +351,9 @@ all: $(all-y) | |||
333 | 351 | ||
334 | # boot | 352 | # boot |
335 | $(boot-y): $(vmlinux-32) FORCE | 353 | $(boot-y): $(vmlinux-32) FORCE |
354 | ifeq ($(CONFIG_RELOCATABLE)$(CONFIG_32BIT),yy) | ||
355 | $(call cmd,relocs) | ||
356 | endif | ||
336 | $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) \ | 357 | $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) \ |
337 | $(bootvars-y) arch/mips/boot/$@ | 358 | $(bootvars-y) arch/mips/boot/$@ |
338 | 359 | ||
@@ -385,6 +406,7 @@ endif | |||
385 | archclean: | 406 | archclean: |
386 | $(Q)$(MAKE) $(clean)=arch/mips/boot | 407 | $(Q)$(MAKE) $(clean)=arch/mips/boot |
387 | $(Q)$(MAKE) $(clean)=arch/mips/boot/compressed | 408 | $(Q)$(MAKE) $(clean)=arch/mips/boot/compressed |
409 | $(Q)$(MAKE) $(clean)=arch/mips/boot/tools | ||
388 | $(Q)$(MAKE) $(clean)=arch/mips/lasat | 410 | $(Q)$(MAKE) $(clean)=arch/mips/lasat |
389 | 411 | ||
390 | define archhelp | 412 | define archhelp |
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index bd34f4093cd9..7ba7ea0a22f8 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c | |||
@@ -1043,8 +1043,7 @@ static int __init alchemy_clk_init(void) | |||
1043 | 1043 | ||
1044 | /* Root of the Alchemy clock tree: external 12MHz crystal osc */ | 1044 | /* Root of the Alchemy clock tree: external 12MHz crystal osc */ |
1045 | c = clk_register_fixed_rate(NULL, ALCHEMY_ROOT_CLK, NULL, | 1045 | c = clk_register_fixed_rate(NULL, ALCHEMY_ROOT_CLK, NULL, |
1046 | CLK_IS_ROOT, | 1046 | 0, ALCHEMY_ROOTCLK_RATE); |
1047 | ALCHEMY_ROOTCLK_RATE); | ||
1048 | ERRCK(c) | 1047 | ERRCK(c) |
1049 | 1048 | ||
1050 | /* CPU core clock */ | 1049 | /* CPU core clock */ |
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 13c04cf54afa..dfc60209dc63 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig | |||
@@ -71,18 +71,6 @@ config ATH79_MACH_UBNT_XM | |||
71 | Say 'Y' here if you want your kernel to support the | 71 | Say 'Y' here if you want your kernel to support the |
72 | Ubiquiti Networks XM (rev 1.0) board. | 72 | Ubiquiti Networks XM (rev 1.0) board. |
73 | 73 | ||
74 | choice | ||
75 | prompt "Build a DTB in the kernel" | ||
76 | optional | ||
77 | help | ||
78 | Select a devicetree that should be built into the kernel. | ||
79 | |||
80 | config DTB_TL_WR1043ND_V1 | ||
81 | bool "TL-WR1043ND Version 1" | ||
82 | select BUILTIN_DTB | ||
83 | select SOC_AR913X | ||
84 | endchoice | ||
85 | |||
86 | endmenu | 74 | endmenu |
87 | 75 | ||
88 | config SOC_AR71XX | 76 | config SOC_AR71XX |
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 618dfd735eed..2e7378467c5c 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c | |||
@@ -18,17 +18,21 @@ | |||
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/clkdev.h> | 19 | #include <linux/clkdev.h> |
20 | #include <linux/clk-provider.h> | 20 | #include <linux/clk-provider.h> |
21 | #include <linux/of.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <dt-bindings/clock/ath79-clk.h> | ||
21 | 24 | ||
22 | #include <asm/div64.h> | 25 | #include <asm/div64.h> |
23 | 26 | ||
24 | #include <asm/mach-ath79/ath79.h> | 27 | #include <asm/mach-ath79/ath79.h> |
25 | #include <asm/mach-ath79/ar71xx_regs.h> | 28 | #include <asm/mach-ath79/ar71xx_regs.h> |
26 | #include "common.h" | 29 | #include "common.h" |
30 | #include "machtypes.h" | ||
27 | 31 | ||
28 | #define AR71XX_BASE_FREQ 40000000 | 32 | #define AR71XX_BASE_FREQ 40000000 |
29 | #define AR724X_BASE_FREQ 40000000 | 33 | #define AR724X_BASE_FREQ 40000000 |
30 | 34 | ||
31 | static struct clk *clks[3]; | 35 | static struct clk *clks[ATH79_CLK_END]; |
32 | static struct clk_onecell_data clk_data = { | 36 | static struct clk_onecell_data clk_data = { |
33 | .clks = clks, | 37 | .clks = clks, |
34 | .clk_num = ARRAY_SIZE(clks), | 38 | .clk_num = ARRAY_SIZE(clks), |
@@ -40,7 +44,7 @@ static struct clk *__init ath79_add_sys_clkdev( | |||
40 | struct clk *clk; | 44 | struct clk *clk; |
41 | int err; | 45 | int err; |
42 | 46 | ||
43 | clk = clk_register_fixed_rate(NULL, id, NULL, CLK_IS_ROOT, rate); | 47 | clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate); |
44 | if (!clk) | 48 | if (!clk) |
45 | panic("failed to allocate %s clock structure", id); | 49 | panic("failed to allocate %s clock structure", id); |
46 | 50 | ||
@@ -78,107 +82,139 @@ static void __init ar71xx_clocks_init(void) | |||
78 | ahb_rate = cpu_rate / div; | 82 | ahb_rate = cpu_rate / div; |
79 | 83 | ||
80 | ath79_add_sys_clkdev("ref", ref_rate); | 84 | ath79_add_sys_clkdev("ref", ref_rate); |
81 | clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); | 85 | clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); |
82 | clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); | 86 | clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); |
83 | clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); | 87 | clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); |
84 | 88 | ||
85 | clk_add_alias("wdt", NULL, "ahb", NULL); | 89 | clk_add_alias("wdt", NULL, "ahb", NULL); |
86 | clk_add_alias("uart", NULL, "ahb", NULL); | 90 | clk_add_alias("uart", NULL, "ahb", NULL); |
87 | } | 91 | } |
88 | 92 | ||
89 | static void __init ar724x_clocks_init(void) | 93 | static struct clk * __init ath79_reg_ffclk(const char *name, |
94 | const char *parent_name, unsigned int mult, unsigned int div) | ||
90 | { | 95 | { |
91 | unsigned long ref_rate; | 96 | struct clk *clk; |
92 | unsigned long cpu_rate; | ||
93 | unsigned long ddr_rate; | ||
94 | unsigned long ahb_rate; | ||
95 | u32 pll; | ||
96 | u32 freq; | ||
97 | u32 div; | ||
98 | 97 | ||
99 | ref_rate = AR724X_BASE_FREQ; | 98 | clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); |
100 | pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); | 99 | if (!clk) |
100 | panic("failed to allocate %s clock structure", name); | ||
101 | 101 | ||
102 | div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); | 102 | return clk; |
103 | freq = div * ref_rate; | 103 | } |
104 | 104 | ||
105 | static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) | ||
106 | { | ||
107 | u32 pll; | ||
108 | u32 mult, div, ddr_div, ahb_div; | ||
109 | |||
110 | pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); | ||
111 | |||
112 | mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); | ||
105 | div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; | 113 | div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; |
106 | freq /= div; | ||
107 | 114 | ||
108 | cpu_rate = freq; | 115 | ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; |
116 | ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; | ||
109 | 117 | ||
110 | div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; | 118 | clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div); |
111 | ddr_rate = freq / div; | 119 | clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div); |
120 | clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div); | ||
121 | } | ||
112 | 122 | ||
113 | div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; | 123 | static void __init ar724x_clocks_init(void) |
114 | ahb_rate = cpu_rate / div; | 124 | { |
125 | struct clk *ref_clk; | ||
115 | 126 | ||
116 | ath79_add_sys_clkdev("ref", ref_rate); | 127 | ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ); |
117 | clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); | 128 | |
118 | clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); | 129 | ar724x_clk_init(ref_clk, ath79_pll_base); |
119 | clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); | 130 | |
131 | /* just make happy plat_time_init() from arch/mips/ath79/setup.c */ | ||
132 | clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL); | ||
133 | clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL); | ||
134 | clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL); | ||
120 | 135 | ||
121 | clk_add_alias("wdt", NULL, "ahb", NULL); | 136 | clk_add_alias("wdt", NULL, "ahb", NULL); |
122 | clk_add_alias("uart", NULL, "ahb", NULL); | 137 | clk_add_alias("uart", NULL, "ahb", NULL); |
123 | } | 138 | } |
124 | 139 | ||
125 | static void __init ar933x_clocks_init(void) | 140 | static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) |
126 | { | 141 | { |
127 | unsigned long ref_rate; | ||
128 | unsigned long cpu_rate; | ||
129 | unsigned long ddr_rate; | ||
130 | unsigned long ahb_rate; | ||
131 | u32 clock_ctrl; | 142 | u32 clock_ctrl; |
132 | u32 cpu_config; | 143 | u32 ref_div; |
133 | u32 freq; | 144 | u32 ninit_mul; |
134 | u32 t; | 145 | u32 out_div; |
135 | 146 | ||
136 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | 147 | u32 cpu_div; |
137 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) | 148 | u32 ddr_div; |
138 | ref_rate = (40 * 1000 * 1000); | 149 | u32 ahb_div; |
139 | else | ||
140 | ref_rate = (25 * 1000 * 1000); | ||
141 | 150 | ||
142 | clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG); | 151 | clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); |
143 | if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { | 152 | if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { |
144 | cpu_rate = ref_rate; | 153 | ref_div = 1; |
145 | ahb_rate = ref_rate; | 154 | ninit_mul = 1; |
146 | ddr_rate = ref_rate; | 155 | out_div = 1; |
156 | |||
157 | cpu_div = 1; | ||
158 | ddr_div = 1; | ||
159 | ahb_div = 1; | ||
147 | } else { | 160 | } else { |
148 | cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG); | 161 | u32 cpu_config; |
162 | u32 t; | ||
163 | |||
164 | cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG); | ||
149 | 165 | ||
150 | t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | 166 | t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & |
151 | AR933X_PLL_CPU_CONFIG_REFDIV_MASK; | 167 | AR933X_PLL_CPU_CONFIG_REFDIV_MASK; |
152 | freq = ref_rate / t; | 168 | ref_div = t; |
153 | 169 | ||
154 | t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & | 170 | ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & |
155 | AR933X_PLL_CPU_CONFIG_NINT_MASK; | 171 | AR933X_PLL_CPU_CONFIG_NINT_MASK; |
156 | freq *= t; | ||
157 | 172 | ||
158 | t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | 173 | t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & |
159 | AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; | 174 | AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; |
160 | if (t == 0) | 175 | if (t == 0) |
161 | t = 1; | 176 | t = 1; |
162 | 177 | ||
163 | freq >>= t; | 178 | out_div = (1 << t); |
164 | 179 | ||
165 | t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & | 180 | cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & |
166 | AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; | 181 | AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; |
167 | cpu_rate = freq / t; | ||
168 | 182 | ||
169 | t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & | 183 | ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & |
170 | AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; | 184 | AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; |
171 | ddr_rate = freq / t; | ||
172 | 185 | ||
173 | t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & | 186 | ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & |
174 | AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; | 187 | AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; |
175 | ahb_rate = freq / t; | ||
176 | } | 188 | } |
177 | 189 | ||
178 | ath79_add_sys_clkdev("ref", ref_rate); | 190 | clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", |
179 | clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); | 191 | ninit_mul, ref_div * out_div * cpu_div); |
180 | clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); | 192 | clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", |
181 | clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); | 193 | ninit_mul, ref_div * out_div * ddr_div); |
194 | clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", | ||
195 | ninit_mul, ref_div * out_div * ahb_div); | ||
196 | } | ||
197 | |||
198 | static void __init ar933x_clocks_init(void) | ||
199 | { | ||
200 | struct clk *ref_clk; | ||
201 | unsigned long ref_rate; | ||
202 | u32 t; | ||
203 | |||
204 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | ||
205 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) | ||
206 | ref_rate = (40 * 1000 * 1000); | ||
207 | else | ||
208 | ref_rate = (25 * 1000 * 1000); | ||
209 | |||
210 | ref_clk = ath79_add_sys_clkdev("ref", ref_rate); | ||
211 | |||
212 | ar9330_clk_init(ref_clk, ath79_pll_base); | ||
213 | |||
214 | /* just make happy plat_time_init() from arch/mips/ath79/setup.c */ | ||
215 | clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL); | ||
216 | clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL); | ||
217 | clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL); | ||
182 | 218 | ||
183 | clk_add_alias("wdt", NULL, "ahb", NULL); | 219 | clk_add_alias("wdt", NULL, "ahb", NULL); |
184 | clk_add_alias("uart", NULL, "ref", NULL); | 220 | clk_add_alias("uart", NULL, "ref", NULL); |
@@ -310,9 +346,9 @@ static void __init ar934x_clocks_init(void) | |||
310 | ahb_rate = cpu_pll / (postdiv + 1); | 346 | ahb_rate = cpu_pll / (postdiv + 1); |
311 | 347 | ||
312 | ath79_add_sys_clkdev("ref", ref_rate); | 348 | ath79_add_sys_clkdev("ref", ref_rate); |
313 | clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); | 349 | clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); |
314 | clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); | 350 | clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); |
315 | clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); | 351 | clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); |
316 | 352 | ||
317 | clk_add_alias("wdt", NULL, "ref", NULL); | 353 | clk_add_alias("wdt", NULL, "ref", NULL); |
318 | clk_add_alias("uart", NULL, "ref", NULL); | 354 | clk_add_alias("uart", NULL, "ref", NULL); |
@@ -397,9 +433,9 @@ static void __init qca955x_clocks_init(void) | |||
397 | ahb_rate = cpu_pll / (postdiv + 1); | 433 | ahb_rate = cpu_pll / (postdiv + 1); |
398 | 434 | ||
399 | ath79_add_sys_clkdev("ref", ref_rate); | 435 | ath79_add_sys_clkdev("ref", ref_rate); |
400 | clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); | 436 | clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); |
401 | clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); | 437 | clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); |
402 | clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); | 438 | clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); |
403 | 439 | ||
404 | clk_add_alias("wdt", NULL, "ref", NULL); | 440 | clk_add_alias("wdt", NULL, "ref", NULL); |
405 | clk_add_alias("uart", NULL, "ref", NULL); | 441 | clk_add_alias("uart", NULL, "ref", NULL); |
@@ -419,8 +455,6 @@ void __init ath79_clocks_init(void) | |||
419 | qca955x_clocks_init(); | 455 | qca955x_clocks_init(); |
420 | else | 456 | else |
421 | BUG(); | 457 | BUG(); |
422 | |||
423 | of_clk_init(NULL); | ||
424 | } | 458 | } |
425 | 459 | ||
426 | unsigned long __init | 460 | unsigned long __init |
@@ -447,8 +481,49 @@ static void __init ath79_clocks_init_dt(struct device_node *np) | |||
447 | 481 | ||
448 | CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt); | 482 | CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt); |
449 | CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt); | 483 | CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt); |
450 | CLK_OF_DECLARE(ar9130, "qca,ar9130-pll", ath79_clocks_init_dt); | ||
451 | CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt); | ||
452 | CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt); | 484 | CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt); |
453 | CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt); | 485 | CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt); |
486 | |||
487 | static void __init ath79_clocks_init_dt_ng(struct device_node *np) | ||
488 | { | ||
489 | struct clk *ref_clk; | ||
490 | void __iomem *pll_base; | ||
491 | const char *dnfn = of_node_full_name(np); | ||
492 | |||
493 | ref_clk = of_clk_get(np, 0); | ||
494 | if (IS_ERR(ref_clk)) { | ||
495 | pr_err("%s: of_clk_get failed\n", dnfn); | ||
496 | goto err; | ||
497 | } | ||
498 | |||
499 | pll_base = of_iomap(np, 0); | ||
500 | if (!pll_base) { | ||
501 | pr_err("%s: can't map pll registers\n", dnfn); | ||
502 | goto err_clk; | ||
503 | } | ||
504 | |||
505 | if (of_device_is_compatible(np, "qca,ar9130-pll")) | ||
506 | ar724x_clk_init(ref_clk, pll_base); | ||
507 | else if (of_device_is_compatible(np, "qca,ar9330-pll")) | ||
508 | ar9330_clk_init(ref_clk, pll_base); | ||
509 | else { | ||
510 | pr_err("%s: could not find any appropriate clk_init()\n", dnfn); | ||
511 | goto err_clk; | ||
512 | } | ||
513 | |||
514 | if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { | ||
515 | pr_err("%s: could not register clk provider\n", dnfn); | ||
516 | goto err_clk; | ||
517 | } | ||
518 | |||
519 | return; | ||
520 | |||
521 | err_clk: | ||
522 | clk_put(ref_clk); | ||
523 | |||
524 | err: | ||
525 | return; | ||
526 | } | ||
527 | CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng); | ||
528 | CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng); | ||
454 | #endif | 529 | #endif |
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c index 3cedd1f95e0f..d071a3a0f876 100644 --- a/arch/mips/ath79/common.c +++ b/arch/mips/ath79/common.c | |||
@@ -46,12 +46,12 @@ void ath79_ddr_ctrl_init(void) | |||
46 | { | 46 | { |
47 | ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, | 47 | ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, |
48 | AR71XX_DDR_CTRL_SIZE); | 48 | AR71XX_DDR_CTRL_SIZE); |
49 | if (soc_is_ar71xx() || soc_is_ar934x()) { | 49 | if (soc_is_ar913x() || soc_is_ar724x() || soc_is_ar933x()) { |
50 | ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; | ||
51 | ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c; | ||
52 | } else { | ||
53 | ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c; | 50 | ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c; |
54 | ath79_ddr_pci_win_base = 0; | 51 | ath79_ddr_pci_win_base = 0; |
52 | } else { | ||
53 | ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; | ||
54 | ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c; | ||
55 | } | 55 | } |
56 | } | 56 | } |
57 | EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init); | 57 | EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init); |
@@ -76,14 +76,14 @@ void ath79_ddr_set_pci_windows(void) | |||
76 | { | 76 | { |
77 | BUG_ON(!ath79_ddr_pci_win_base); | 77 | BUG_ON(!ath79_ddr_pci_win_base); |
78 | 78 | ||
79 | __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0); | 79 | __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0x0); |
80 | __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 1); | 80 | __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 0x4); |
81 | __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 2); | 81 | __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 0x8); |
82 | __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 3); | 82 | __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 0xc); |
83 | __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 4); | 83 | __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 0x10); |
84 | __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 5); | 84 | __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 0x14); |
85 | __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 6); | 85 | __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 0x18); |
86 | __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 7); | 86 | __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 0x1c); |
87 | } | 87 | } |
88 | EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows); | 88 | EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows); |
89 | 89 | ||
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index be451ee4a5ea..7adab180e0ca 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/bootmem.h> | 17 | #include <linux/bootmem.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/clk-provider.h> | ||
20 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
21 | #include <linux/of_fdt.h> | 22 | #include <linux/of_fdt.h> |
22 | 23 | ||
@@ -203,26 +204,57 @@ void __init plat_mem_setup(void) | |||
203 | fdt_start = fw_getenvl("fdt_start"); | 204 | fdt_start = fw_getenvl("fdt_start"); |
204 | if (fdt_start) | 205 | if (fdt_start) |
205 | __dt_setup_arch((void *)KSEG0ADDR(fdt_start)); | 206 | __dt_setup_arch((void *)KSEG0ADDR(fdt_start)); |
206 | #ifdef CONFIG_BUILTIN_DTB | 207 | else if (fw_arg0 == -2) |
207 | else | 208 | __dt_setup_arch((void *)KSEG0ADDR(fw_arg1)); |
208 | __dt_setup_arch(__dtb_start); | ||
209 | #endif | ||
210 | 209 | ||
211 | ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, | 210 | if (mips_machtype != ATH79_MACH_GENERIC_OF) { |
212 | AR71XX_RESET_SIZE); | 211 | ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, |
213 | ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, | 212 | AR71XX_RESET_SIZE); |
214 | AR71XX_PLL_SIZE); | 213 | ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, |
215 | ath79_detect_sys_type(); | 214 | AR71XX_PLL_SIZE); |
216 | ath79_ddr_ctrl_init(); | 215 | ath79_detect_sys_type(); |
216 | ath79_ddr_ctrl_init(); | ||
217 | 217 | ||
218 | if (mips_machtype != ATH79_MACH_GENERIC_OF) | ||
219 | detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); | 218 | detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); |
220 | 219 | ||
221 | _machine_restart = ath79_restart; | 220 | /* OF machines should use the reset driver */ |
221 | _machine_restart = ath79_restart; | ||
222 | } | ||
223 | |||
222 | _machine_halt = ath79_halt; | 224 | _machine_halt = ath79_halt; |
223 | pm_power_off = ath79_halt; | 225 | pm_power_off = ath79_halt; |
224 | } | 226 | } |
225 | 227 | ||
228 | static void __init ath79_of_plat_time_init(void) | ||
229 | { | ||
230 | struct device_node *np; | ||
231 | struct clk *clk; | ||
232 | unsigned long cpu_clk_rate; | ||
233 | |||
234 | of_clk_init(NULL); | ||
235 | |||
236 | np = of_get_cpu_node(0, NULL); | ||
237 | if (!np) { | ||
238 | pr_err("Failed to get CPU node\n"); | ||
239 | return; | ||
240 | } | ||
241 | |||
242 | clk = of_clk_get(np, 0); | ||
243 | if (IS_ERR(clk)) { | ||
244 | pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); | ||
245 | return; | ||
246 | } | ||
247 | |||
248 | cpu_clk_rate = clk_get_rate(clk); | ||
249 | |||
250 | pr_info("CPU clock: %lu.%03lu MHz\n", | ||
251 | cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000); | ||
252 | |||
253 | mips_hpt_frequency = cpu_clk_rate / 2; | ||
254 | |||
255 | clk_put(clk); | ||
256 | } | ||
257 | |||
226 | void __init plat_time_init(void) | 258 | void __init plat_time_init(void) |
227 | { | 259 | { |
228 | unsigned long cpu_clk_rate; | 260 | unsigned long cpu_clk_rate; |
@@ -230,6 +262,11 @@ void __init plat_time_init(void) | |||
230 | unsigned long ddr_clk_rate; | 262 | unsigned long ddr_clk_rate; |
231 | unsigned long ref_clk_rate; | 263 | unsigned long ref_clk_rate; |
232 | 264 | ||
265 | if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) { | ||
266 | ath79_of_plat_time_init(); | ||
267 | return; | ||
268 | } | ||
269 | |||
233 | ath79_clocks_init(); | 270 | ath79_clocks_init(); |
234 | 271 | ||
235 | cpu_clk_rate = ath79_get_sys_clk_rate("cpu"); | 272 | cpu_clk_rate = ath79_get_sys_clk_rate("cpu"); |
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index 66bea4ecf449..6d8615074075 100644 --- a/arch/mips/bcm47xx/Makefile +++ b/arch/mips/bcm47xx/Makefile | |||
@@ -3,5 +3,5 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += irq.o prom.o serial.o setup.o time.o sprom.o | 6 | obj-y += irq.o prom.o serial.o setup.o time.o |
7 | obj-y += board.o buttons.o leds.o workarounds.o | 7 | obj-y += board.o buttons.o leds.o workarounds.o |
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h index 41796befa9df..0367ac7286fe 100644 --- a/arch/mips/bcm47xx/bcm47xx_private.h +++ b/arch/mips/bcm47xx/bcm47xx_private.h | |||
@@ -10,9 +10,6 @@ | |||
10 | /* prom.c */ | 10 | /* prom.c */ |
11 | void __init bcm47xx_prom_highmem_init(void); | 11 | void __init bcm47xx_prom_highmem_init(void); |
12 | 12 | ||
13 | /* sprom.c */ | ||
14 | void bcm47xx_sprom_register_fallbacks(void); | ||
15 | |||
16 | /* buttons.c */ | 13 | /* buttons.c */ |
17 | int __init bcm47xx_buttons_register(void); | 14 | int __init bcm47xx_buttons_register(void); |
18 | 15 | ||
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index c807e32d6d81..6054d49e608e 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "bcm47xx_private.h" | 29 | #include "bcm47xx_private.h" |
30 | 30 | ||
31 | #include <linux/bcm47xx_sprom.h> | ||
31 | #include <linux/export.h> | 32 | #include <linux/export.h> |
32 | #include <linux/types.h> | 33 | #include <linux/types.h> |
33 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
@@ -151,7 +152,6 @@ void __init plat_mem_setup(void) | |||
151 | pr_info("Using bcma bus\n"); | 152 | pr_info("Using bcma bus\n"); |
152 | #ifdef CONFIG_BCM47XX_BCMA | 153 | #ifdef CONFIG_BCM47XX_BCMA |
153 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; | 154 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; |
154 | bcm47xx_sprom_register_fallbacks(); | ||
155 | bcm47xx_register_bcma(); | 155 | bcm47xx_register_bcma(); |
156 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); | 156 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); |
157 | #ifdef CONFIG_HIGHMEM | 157 | #ifdef CONFIG_HIGHMEM |
diff --git a/arch/mips/bmips/Kconfig b/arch/mips/bmips/Kconfig index e2c4fd682c74..264328d528c7 100644 --- a/arch/mips/bmips/Kconfig +++ b/arch/mips/bmips/Kconfig | |||
@@ -21,6 +21,10 @@ config DT_BCM93384WVG_VIPER | |||
21 | bool "BCM93384WVG Viper CPU (EXPERIMENTAL)" | 21 | bool "BCM93384WVG Viper CPU (EXPERIMENTAL)" |
22 | select BUILTIN_DTB | 22 | select BUILTIN_DTB |
23 | 23 | ||
24 | config DT_BCM96358NB4SER | ||
25 | bool "BCM96358NB4SER" | ||
26 | select BUILTIN_DTB | ||
27 | |||
24 | config DT_BCM96368MVWG | 28 | config DT_BCM96368MVWG |
25 | bool "BCM96368MVWG" | 29 | bool "BCM96368MVWG" |
26 | select BUILTIN_DTB | 30 | select BUILTIN_DTB |
diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c index 35535284b39e..f146d1219bde 100644 --- a/arch/mips/bmips/setup.c +++ b/arch/mips/bmips/setup.c | |||
@@ -95,6 +95,15 @@ static void bcm6328_quirks(void) | |||
95 | bcm63xx_fixup_cpu1(); | 95 | bcm63xx_fixup_cpu1(); |
96 | } | 96 | } |
97 | 97 | ||
98 | static void bcm6358_quirks(void) | ||
99 | { | ||
100 | /* | ||
101 | * BCM6358 needs special handling for its shared TLB, so | ||
102 | * disable SMP for now | ||
103 | */ | ||
104 | bmips_smp_enabled = 0; | ||
105 | } | ||
106 | |||
98 | static void bcm6368_quirks(void) | 107 | static void bcm6368_quirks(void) |
99 | { | 108 | { |
100 | bcm63xx_fixup_cpu1(); | 109 | bcm63xx_fixup_cpu1(); |
@@ -104,13 +113,16 @@ static const struct bmips_quirk bmips_quirk_list[] = { | |||
104 | { "brcm,bcm3384-viper", &bcm3384_viper_quirks }, | 113 | { "brcm,bcm3384-viper", &bcm3384_viper_quirks }, |
105 | { "brcm,bcm33843-viper", &bcm3384_viper_quirks }, | 114 | { "brcm,bcm33843-viper", &bcm3384_viper_quirks }, |
106 | { "brcm,bcm6328", &bcm6328_quirks }, | 115 | { "brcm,bcm6328", &bcm6328_quirks }, |
116 | { "brcm,bcm6358", &bcm6358_quirks }, | ||
107 | { "brcm,bcm6368", &bcm6368_quirks }, | 117 | { "brcm,bcm6368", &bcm6368_quirks }, |
108 | { "brcm,bcm63168", &bcm6368_quirks }, | 118 | { "brcm,bcm63168", &bcm6368_quirks }, |
119 | { "brcm,bcm63268", &bcm6368_quirks }, | ||
109 | { }, | 120 | { }, |
110 | }; | 121 | }; |
111 | 122 | ||
112 | void __init prom_init(void) | 123 | void __init prom_init(void) |
113 | { | 124 | { |
125 | bmips_cpu_setup(); | ||
114 | register_bmips_smp_ops(); | 126 | register_bmips_smp_ops(); |
115 | } | 127 | } |
116 | 128 | ||
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 309d2ad67e4d..90aca95fe314 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile | |||
@@ -37,8 +37,13 @@ vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o | |||
37 | vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o | 37 | vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o |
38 | vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o | 38 | vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o |
39 | vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o | 39 | vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o |
40 | vmlinuzobjs-$(CONFIG_ATH79) += $(obj)/uart-ath79.o | ||
40 | endif | 41 | endif |
41 | 42 | ||
43 | extra-y += uart-ath79.c | ||
44 | $(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c | ||
45 | $(call cmd,shipped) | ||
46 | |||
42 | vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o $(obj)/bswapsi.o | 47 | vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o $(obj)/bswapsi.o |
43 | 48 | ||
44 | extra-y += ashldi3.c bswapsi.c | 49 | extra-y += ashldi3.c bswapsi.c |
diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile index eabeb603e805..fda9d387cc08 100644 --- a/arch/mips/boot/dts/brcm/Makefile +++ b/arch/mips/boot/dts/brcm/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | dtb-$(CONFIG_DT_BCM93384WVG) += bcm93384wvg.dtb | 1 | dtb-$(CONFIG_DT_BCM93384WVG) += bcm93384wvg.dtb |
2 | dtb-$(CONFIG_DT_BCM93384WVG_VIPER) += bcm93384wvg_viper.dtb | 2 | dtb-$(CONFIG_DT_BCM93384WVG_VIPER) += bcm93384wvg_viper.dtb |
3 | dtb-$(CONFIG_DT_BCM96358NB4SER) += bcm96358nb4ser.dtb | ||
3 | dtb-$(CONFIG_DT_BCM96368MVWG) += bcm96368mvwg.dtb | 4 | dtb-$(CONFIG_DT_BCM96368MVWG) += bcm96368mvwg.dtb |
4 | dtb-$(CONFIG_DT_BCM9EJTAGPRB) += bcm9ejtagprb.dtb | 5 | dtb-$(CONFIG_DT_BCM9EJTAGPRB) += bcm9ejtagprb.dtb |
5 | dtb-$(CONFIG_DT_BCM97125CBMB) += bcm97125cbmb.dtb | 6 | dtb-$(CONFIG_DT_BCM97125CBMB) += bcm97125cbmb.dtb |
@@ -14,6 +15,7 @@ dtb-$(CONFIG_DT_BCM97435SVMB) += bcm97435svmb.dtb | |||
14 | dtb-$(CONFIG_DT_NONE) += \ | 15 | dtb-$(CONFIG_DT_NONE) += \ |
15 | bcm93384wvg.dtb \ | 16 | bcm93384wvg.dtb \ |
16 | bcm93384wvg_viper.dtb \ | 17 | bcm93384wvg_viper.dtb \ |
18 | bcm96358nb4ser.dtb \ | ||
17 | bcm96368mvwg.dtb \ | 19 | bcm96368mvwg.dtb \ |
18 | bcm9ejtagprb.dtb \ | 20 | bcm9ejtagprb.dtb \ |
19 | bcm97125cbmb.dtb \ | 21 | bcm97125cbmb.dtb \ |
diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi index 9d19236f53e7..5633b9d90f55 100644 --- a/arch/mips/boot/dts/brcm/bcm6328.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi | |||
@@ -23,7 +23,7 @@ | |||
23 | }; | 23 | }; |
24 | 24 | ||
25 | clocks { | 25 | clocks { |
26 | periph_clk: periph_clk { | 26 | periph_clk: periph-clk { |
27 | compatible = "fixed-clock"; | 27 | compatible = "fixed-clock"; |
28 | #clock-cells = <0>; | 28 | #clock-cells = <0>; |
29 | clock-frequency = <50000000>; | 29 | clock-frequency = <50000000>; |
@@ -31,11 +31,11 @@ | |||
31 | }; | 31 | }; |
32 | 32 | ||
33 | aliases { | 33 | aliases { |
34 | leds0 = &leds0; | 34 | serial0 = &uart0; |
35 | uart0 = &uart0; | 35 | serial1 = &uart1; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | cpu_intc: cpu_intc { | 38 | cpu_intc: interrupt-controller { |
39 | #address-cells = <0>; | 39 | #address-cells = <0>; |
40 | compatible = "mti,cpu-interrupt-controller"; | 40 | compatible = "mti,cpu-interrupt-controller"; |
41 | 41 | ||
@@ -50,16 +50,16 @@ | |||
50 | compatible = "simple-bus"; | 50 | compatible = "simple-bus"; |
51 | ranges; | 51 | ranges; |
52 | 52 | ||
53 | periph_intc: periph_intc@10000020 { | 53 | periph_intc: interrupt-controller@10000020 { |
54 | compatible = "brcm,bcm3380-l2-intc"; | 54 | compatible = "brcm,bcm6345-l1-intc"; |
55 | reg = <0x10000024 0x4 0x1000002c 0x4>, | 55 | reg = <0x10000020 0x10>, |
56 | <0x10000020 0x4 0x10000028 0x4>; | 56 | <0x10000030 0x10>; |
57 | 57 | ||
58 | interrupt-controller; | 58 | interrupt-controller; |
59 | #interrupt-cells = <1>; | 59 | #interrupt-cells = <1>; |
60 | 60 | ||
61 | interrupt-parent = <&cpu_intc>; | 61 | interrupt-parent = <&cpu_intc>; |
62 | interrupts = <2>; | 62 | interrupts = <2>, <3>; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | uart0: serial@10000100 { | 65 | uart0: serial@10000100 { |
@@ -71,13 +71,22 @@ | |||
71 | status = "disabled"; | 71 | status = "disabled"; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | timer: timer@10000040 { | 74 | uart1: serial@10000120 { |
75 | compatible = "brcm,bcm6345-uart"; | ||
76 | reg = <0x10000120 0x18>; | ||
77 | interrupt-parent = <&periph_intc>; | ||
78 | interrupts = <39>; | ||
79 | clocks = <&periph_clk>; | ||
80 | status = "disabled"; | ||
81 | }; | ||
82 | |||
83 | timer: syscon@10000040 { | ||
75 | compatible = "syscon"; | 84 | compatible = "syscon"; |
76 | reg = <0x10000040 0x2c>; | 85 | reg = <0x10000040 0x2c>; |
77 | native-endian; | 86 | native-endian; |
78 | }; | 87 | }; |
79 | 88 | ||
80 | reboot { | 89 | reboot: syscon-reboot@10000068 { |
81 | compatible = "syscon-reboot"; | 90 | compatible = "syscon-reboot"; |
82 | regmap = <&timer>; | 91 | regmap = <&timer>; |
83 | offset = <0x28>; | 92 | offset = <0x28>; |
@@ -91,5 +100,24 @@ | |||
91 | reg = <0x10000800 0x24>; | 100 | reg = <0x10000800 0x24>; |
92 | status = "disabled"; | 101 | status = "disabled"; |
93 | }; | 102 | }; |
103 | |||
104 | ehci: usb@10002500 { | ||
105 | compatible = "brcm,bcm6328-ehci", "generic-ehci"; | ||
106 | reg = <0x10002500 0x100>; | ||
107 | big-endian; | ||
108 | interrupt-parent = <&periph_intc>; | ||
109 | interrupts = <42>; | ||
110 | status = "disabled"; | ||
111 | }; | ||
112 | |||
113 | ohci: usb@10002600 { | ||
114 | compatible = "brcm,bcm6328-ohci", "generic-ohci"; | ||
115 | reg = <0x10002600 0x100>; | ||
116 | big-endian; | ||
117 | no-big-frame-no; | ||
118 | interrupt-parent = <&periph_intc>; | ||
119 | interrupts = <41>; | ||
120 | status = "disabled"; | ||
121 | }; | ||
94 | }; | 122 | }; |
95 | }; | 123 | }; |
diff --git a/arch/mips/boot/dts/brcm/bcm6358.dtsi b/arch/mips/boot/dts/brcm/bcm6358.dtsi new file mode 100644 index 000000000000..f9d8d392162b --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm6358.dtsi | |||
@@ -0,0 +1,130 @@ | |||
1 | / { | ||
2 | #address-cells = <1>; | ||
3 | #size-cells = <1>; | ||
4 | compatible = "brcm,bcm6358"; | ||
5 | |||
6 | cpus { | ||
7 | #address-cells = <1>; | ||
8 | #size-cells = <0>; | ||
9 | |||
10 | mips-hpt-frequency = <150000000>; | ||
11 | |||
12 | cpu@0 { | ||
13 | compatible = "brcm,bmips4350"; | ||
14 | device_type = "cpu"; | ||
15 | reg = <0>; | ||
16 | }; | ||
17 | |||
18 | cpu@1 { | ||
19 | compatible = "brcm,bmips4350"; | ||
20 | device_type = "cpu"; | ||
21 | reg = <1>; | ||
22 | }; | ||
23 | }; | ||
24 | |||
25 | clocks { | ||
26 | periph_clk: periph-clk { | ||
27 | compatible = "fixed-clock"; | ||
28 | #clock-cells = <0>; | ||
29 | clock-frequency = <50000000>; | ||
30 | }; | ||
31 | }; | ||
32 | |||
33 | aliases { | ||
34 | serial0 = &uart0; | ||
35 | serial1 = &uart1; | ||
36 | }; | ||
37 | |||
38 | cpu_intc: interrupt-controller { | ||
39 | #address-cells = <0>; | ||
40 | compatible = "mti,cpu-interrupt-controller"; | ||
41 | |||
42 | interrupt-controller; | ||
43 | #interrupt-cells = <1>; | ||
44 | }; | ||
45 | |||
46 | ubus { | ||
47 | #address-cells = <1>; | ||
48 | #size-cells = <1>; | ||
49 | |||
50 | compatible = "simple-bus"; | ||
51 | ranges; | ||
52 | |||
53 | periph_cntl: syscon@fffe0000 { | ||
54 | compatible = "syscon"; | ||
55 | reg = <0xfffe0000 0xc>; | ||
56 | native-endian; | ||
57 | }; | ||
58 | |||
59 | reboot: syscon-reboot@fffe0008 { | ||
60 | compatible = "syscon-reboot"; | ||
61 | regmap = <&periph_cntl>; | ||
62 | offset = <0x8>; | ||
63 | mask = <0x1>; | ||
64 | }; | ||
65 | |||
66 | periph_intc: interrupt-controller@fffe000c { | ||
67 | compatible = "brcm,bcm6345-l1-intc"; | ||
68 | reg = <0xfffe000c 0x8>, | ||
69 | <0xfffe0038 0x8>; | ||
70 | |||
71 | interrupt-controller; | ||
72 | #interrupt-cells = <1>; | ||
73 | |||
74 | interrupt-parent = <&cpu_intc>; | ||
75 | interrupts = <2>, <3>; | ||
76 | }; | ||
77 | |||
78 | leds0: led-controller@fffe00d0 { | ||
79 | #address-cells = <1>; | ||
80 | #size-cells = <0>; | ||
81 | compatible = "brcm,bcm6358-leds"; | ||
82 | reg = <0xfffe00d0 0x8>; | ||
83 | |||
84 | status = "disabled"; | ||
85 | }; | ||
86 | |||
87 | uart0: serial@fffe0100 { | ||
88 | compatible = "brcm,bcm6345-uart"; | ||
89 | reg = <0xfffe0100 0x18>; | ||
90 | |||
91 | interrupt-parent = <&periph_intc>; | ||
92 | interrupts = <2>; | ||
93 | |||
94 | clocks = <&periph_clk>; | ||
95 | |||
96 | status = "disabled"; | ||
97 | }; | ||
98 | |||
99 | uart1: serial@fffe0120 { | ||
100 | compatible = "brcm,bcm6345-uart"; | ||
101 | reg = <0xfffe0120 0x18>; | ||
102 | |||
103 | interrupt-parent = <&periph_intc>; | ||
104 | interrupts = <3>; | ||
105 | |||
106 | clocks = <&periph_clk>; | ||
107 | |||
108 | status = "disabled"; | ||
109 | }; | ||
110 | |||
111 | ehci: usb@fffe1300 { | ||
112 | compatible = "brcm,bcm6358-ehci", "generic-ehci"; | ||
113 | reg = <0xfffe1300 0x100>; | ||
114 | big-endian; | ||
115 | interrupt-parent = <&periph_intc>; | ||
116 | interrupts = <10>; | ||
117 | status = "disabled"; | ||
118 | }; | ||
119 | |||
120 | ohci: usb@fffe1400 { | ||
121 | compatible = "brcm,bcm6358-ohci", "generic-ohci"; | ||
122 | reg = <0xfffe1400 0x100>; | ||
123 | big-endian; | ||
124 | no-big-frame-no; | ||
125 | interrupt-parent = <&periph_intc>; | ||
126 | interrupts = <5>; | ||
127 | status = "disabled"; | ||
128 | }; | ||
129 | }; | ||
130 | }; | ||
diff --git a/arch/mips/boot/dts/brcm/bcm6368.dtsi b/arch/mips/boot/dts/brcm/bcm6368.dtsi index 1f6b9b5cddb4..d0e3a70b32e2 100644 --- a/arch/mips/boot/dts/brcm/bcm6368.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6368.dtsi | |||
@@ -20,11 +20,10 @@ | |||
20 | device_type = "cpu"; | 20 | device_type = "cpu"; |
21 | reg = <1>; | 21 | reg = <1>; |
22 | }; | 22 | }; |
23 | |||
24 | }; | 23 | }; |
25 | 24 | ||
26 | clocks { | 25 | clocks { |
27 | periph_clk: periph_clk { | 26 | periph_clk: periph-clk { |
28 | compatible = "fixed-clock"; | 27 | compatible = "fixed-clock"; |
29 | #clock-cells = <0>; | 28 | #clock-cells = <0>; |
30 | clock-frequency = <50000000>; | 29 | clock-frequency = <50000000>; |
@@ -32,11 +31,11 @@ | |||
32 | }; | 31 | }; |
33 | 32 | ||
34 | aliases { | 33 | aliases { |
35 | leds0 = &leds0; | 34 | serial0 = &uart0; |
36 | uart0 = &uart0; | 35 | serial1 = &uart1; |
37 | }; | 36 | }; |
38 | 37 | ||
39 | cpu_intc: cpu_intc { | 38 | cpu_intc: interrupt-controller { |
40 | #address-cells = <0>; | 39 | #address-cells = <0>; |
41 | compatible = "mti,cpu-interrupt-controller"; | 40 | compatible = "mti,cpu-interrupt-controller"; |
42 | 41 | ||
@@ -64,16 +63,16 @@ | |||
64 | mask = <0x1>; | 63 | mask = <0x1>; |
65 | }; | 64 | }; |
66 | 65 | ||
67 | periph_intc: periph_intc@10000020 { | 66 | periph_intc: interrupt-controller@10000020 { |
68 | compatible = "brcm,bcm3380-l2-intc"; | 67 | compatible = "brcm,bcm6345-l1-intc"; |
69 | reg = <0x10000024 0x4 0x1000002c 0x4>, | 68 | reg = <0x10000020 0x10>, |
70 | <0x10000020 0x4 0x10000028 0x4>; | 69 | <0x10000030 0x10>; |
71 | 70 | ||
72 | interrupt-controller; | 71 | interrupt-controller; |
73 | #interrupt-cells = <1>; | 72 | #interrupt-cells = <1>; |
74 | 73 | ||
75 | interrupt-parent = <&cpu_intc>; | 74 | interrupt-parent = <&cpu_intc>; |
76 | interrupts = <2>; | 75 | interrupts = <2>, <3>; |
77 | }; | 76 | }; |
78 | 77 | ||
79 | leds0: led-controller@100000d0 { | 78 | leds0: led-controller@100000d0 { |
@@ -93,7 +92,16 @@ | |||
93 | status = "disabled"; | 92 | status = "disabled"; |
94 | }; | 93 | }; |
95 | 94 | ||
96 | ehci0: usb@10001500 { | 95 | uart1: serial@10000120 { |
96 | compatible = "brcm,bcm6345-uart"; | ||
97 | reg = <0x10000120 0x18>; | ||
98 | interrupt-parent = <&periph_intc>; | ||
99 | interrupts = <3>; | ||
100 | clocks = <&periph_clk>; | ||
101 | status = "disabled"; | ||
102 | }; | ||
103 | |||
104 | ehci: usb@10001500 { | ||
97 | compatible = "brcm,bcm6368-ehci", "generic-ehci"; | 105 | compatible = "brcm,bcm6368-ehci", "generic-ehci"; |
98 | reg = <0x10001500 0x100>; | 106 | reg = <0x10001500 0x100>; |
99 | big-endian; | 107 | big-endian; |
@@ -102,7 +110,7 @@ | |||
102 | status = "disabled"; | 110 | status = "disabled"; |
103 | }; | 111 | }; |
104 | 112 | ||
105 | ohci0: usb@10001600 { | 113 | ohci: usb@10001600 { |
106 | compatible = "brcm,bcm6368-ohci", "generic-ohci"; | 114 | compatible = "brcm,bcm6368-ohci", "generic-ohci"; |
107 | reg = <0x10001600 0x100>; | 115 | reg = <0x10001600 0x100>; |
108 | big-endian; | 116 | big-endian; |
diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi index 3ae16053a0c9..550e1d9e3ee0 100644 --- a/arch/mips/boot/dts/brcm/bcm7125.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi | |||
@@ -85,14 +85,15 @@ | |||
85 | compatible = "brcm,bcm7120-l2-intc"; | 85 | compatible = "brcm,bcm7120-l2-intc"; |
86 | reg = <0x406780 0x8>; | 86 | reg = <0x406780 0x8>; |
87 | 87 | ||
88 | brcm,int-map-mask = <0x44>; | 88 | brcm,int-map-mask = <0x44>, <0xf000000>; |
89 | brcm,int-fwd-mask = <0x70000>; | 89 | brcm,int-fwd-mask = <0x70000>; |
90 | 90 | ||
91 | interrupt-controller; | 91 | interrupt-controller; |
92 | #interrupt-cells = <1>; | 92 | #interrupt-cells = <1>; |
93 | 93 | ||
94 | interrupt-parent = <&periph_intc>; | 94 | interrupt-parent = <&periph_intc>; |
95 | interrupts = <18>; | 95 | interrupts = <18>, <19>; |
96 | interrupt-names = "upg_main", "upg_bsc"; | ||
96 | }; | 97 | }; |
97 | 98 | ||
98 | sun_top_ctrl: syscon@404000 { | 99 | sun_top_ctrl: syscon@404000 { |
@@ -118,6 +119,70 @@ | |||
118 | status = "disabled"; | 119 | status = "disabled"; |
119 | }; | 120 | }; |
120 | 121 | ||
122 | uart1: serial@406b40 { | ||
123 | compatible = "ns16550a"; | ||
124 | reg = <0x406b40 0x20>; | ||
125 | reg-io-width = <0x4>; | ||
126 | reg-shift = <0x2>; | ||
127 | native-endian; | ||
128 | interrupt-parent = <&periph_intc>; | ||
129 | interrupts = <64>; | ||
130 | clocks = <&uart_clk>; | ||
131 | status = "disabled"; | ||
132 | }; | ||
133 | |||
134 | uart2: serial@406b80 { | ||
135 | compatible = "ns16550a"; | ||
136 | reg = <0x406b80 0x20>; | ||
137 | reg-io-width = <0x4>; | ||
138 | reg-shift = <0x2>; | ||
139 | native-endian; | ||
140 | interrupt-parent = <&periph_intc>; | ||
141 | interrupts = <65>; | ||
142 | clocks = <&uart_clk>; | ||
143 | status = "disabled"; | ||
144 | }; | ||
145 | |||
146 | bsca: i2c@406200 { | ||
147 | clock-frequency = <390000>; | ||
148 | compatible = "brcm,brcmstb-i2c"; | ||
149 | interrupt-parent = <&upg_irq0_intc>; | ||
150 | reg = <0x406200 0x58>; | ||
151 | interrupts = <24>; | ||
152 | interrupt-names = "upg_bsca"; | ||
153 | status = "disabled"; | ||
154 | }; | ||
155 | |||
156 | bscb: i2c@406280 { | ||
157 | clock-frequency = <390000>; | ||
158 | compatible = "brcm,brcmstb-i2c"; | ||
159 | interrupt-parent = <&upg_irq0_intc>; | ||
160 | reg = <0x406280 0x58>; | ||
161 | interrupts = <25>; | ||
162 | interrupt-names = "upg_bscb"; | ||
163 | status = "disabled"; | ||
164 | }; | ||
165 | |||
166 | bscc: i2c@406300 { | ||
167 | clock-frequency = <390000>; | ||
168 | compatible = "brcm,brcmstb-i2c"; | ||
169 | interrupt-parent = <&upg_irq0_intc>; | ||
170 | reg = <0x406300 0x58>; | ||
171 | interrupts = <26>; | ||
172 | interrupt-names = "upg_bscc"; | ||
173 | status = "disabled"; | ||
174 | }; | ||
175 | |||
176 | bscd: i2c@406380 { | ||
177 | clock-frequency = <390000>; | ||
178 | compatible = "brcm,brcmstb-i2c"; | ||
179 | interrupt-parent = <&upg_irq0_intc>; | ||
180 | reg = <0x406380 0x58>; | ||
181 | interrupts = <27>; | ||
182 | interrupt-names = "upg_bscd"; | ||
183 | status = "disabled"; | ||
184 | }; | ||
185 | |||
121 | ehci0: usb@488300 { | 186 | ehci0: usb@488300 { |
122 | compatible = "brcm,bcm7125-ehci", "generic-ehci"; | 187 | compatible = "brcm,bcm7125-ehci", "generic-ehci"; |
123 | reg = <0x488300 0x100>; | 188 | reg = <0x488300 0x100>; |
diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index be7991917d29..ec959061d52e 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi | |||
@@ -24,8 +24,6 @@ | |||
24 | 24 | ||
25 | aliases { | 25 | aliases { |
26 | uart0 = &uart0; | 26 | uart0 = &uart0; |
27 | uart1 = &uart1; | ||
28 | uart2 = &uart2; | ||
29 | }; | 27 | }; |
30 | 28 | ||
31 | cpu_intc: cpu_intc { | 29 | cpu_intc: cpu_intc { |
@@ -323,8 +321,6 @@ | |||
323 | interrupts = <40>; | 321 | interrupts = <40>; |
324 | #address-cells = <1>; | 322 | #address-cells = <1>; |
325 | #size-cells = <0>; | 323 | #size-cells = <0>; |
326 | brcm,broken-ncq; | ||
327 | brcm,broken-phy; | ||
328 | status = "disabled"; | 324 | status = "disabled"; |
329 | 325 | ||
330 | sata0: sata-port@0 { | 326 | sata0: sata-port@0 { |
@@ -338,7 +334,7 @@ | |||
338 | }; | 334 | }; |
339 | }; | 335 | }; |
340 | 336 | ||
341 | sata_phy: sata-phy@1800000 { | 337 | sata_phy: sata-phy@180100 { |
342 | compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; | 338 | compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; |
343 | reg = <0x180100 0x0eff>; | 339 | reg = <0x180100 0x0eff>; |
344 | reg-names = "phy"; | 340 | reg-names = "phy"; |
diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi index 060805be619a..ca57fb5eb122 100644 --- a/arch/mips/boot/dts/brcm/bcm7358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi | |||
@@ -18,8 +18,6 @@ | |||
18 | 18 | ||
19 | aliases { | 19 | aliases { |
20 | uart0 = &uart0; | 20 | uart0 = &uart0; |
21 | uart1 = &uart1; | ||
22 | uart2 = &uart2; | ||
23 | }; | 21 | }; |
24 | 22 | ||
25 | cpu_intc: cpu_intc { | 23 | cpu_intc: cpu_intc { |
diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index bcdb09bfe07b..1c0c3d438c7a 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi | |||
@@ -18,8 +18,6 @@ | |||
18 | 18 | ||
19 | aliases { | 19 | aliases { |
20 | uart0 = &uart0; | 20 | uart0 = &uart0; |
21 | uart1 = &uart1; | ||
22 | uart2 = &uart2; | ||
23 | }; | 21 | }; |
24 | 22 | ||
25 | cpu_intc: cpu_intc { | 23 | cpu_intc: cpu_intc { |
@@ -241,5 +239,45 @@ | |||
241 | interrupts = <66>; | 239 | interrupts = <66>; |
242 | status = "disabled"; | 240 | status = "disabled"; |
243 | }; | 241 | }; |
242 | |||
243 | sata: sata@181000 { | ||
244 | compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; | ||
245 | reg-names = "ahci", "top-ctrl"; | ||
246 | reg = <0x181000 0xa9c>, <0x180020 0x1c>; | ||
247 | interrupt-parent = <&periph_intc>; | ||
248 | interrupts = <86>; | ||
249 | #address-cells = <1>; | ||
250 | #size-cells = <0>; | ||
251 | status = "disabled"; | ||
252 | |||
253 | sata0: sata-port@0 { | ||
254 | reg = <0>; | ||
255 | phys = <&sata_phy0>; | ||
256 | }; | ||
257 | |||
258 | sata1: sata-port@1 { | ||
259 | reg = <1>; | ||
260 | phys = <&sata_phy1>; | ||
261 | }; | ||
262 | }; | ||
263 | |||
264 | sata_phy: sata-phy@180100 { | ||
265 | compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; | ||
266 | reg = <0x180100 0x0eff>; | ||
267 | reg-names = "phy"; | ||
268 | #address-cells = <1>; | ||
269 | #size-cells = <0>; | ||
270 | status = "disabled"; | ||
271 | |||
272 | sata_phy0: sata-phy@0 { | ||
273 | reg = <0>; | ||
274 | #phy-cells = <0>; | ||
275 | }; | ||
276 | |||
277 | sata_phy1: sata-phy@1 { | ||
278 | reg = <1>; | ||
279 | #phy-cells = <0>; | ||
280 | }; | ||
281 | }; | ||
244 | }; | 282 | }; |
245 | }; | 283 | }; |
diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index d3b1b762e6c3..6b4713add4b8 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi | |||
@@ -24,8 +24,6 @@ | |||
24 | 24 | ||
25 | aliases { | 25 | aliases { |
26 | uart0 = &uart0; | 26 | uart0 = &uart0; |
27 | uart1 = &uart1; | ||
28 | uart2 = &uart2; | ||
29 | }; | 27 | }; |
30 | 28 | ||
31 | cpu_intc: cpu_intc { | 29 | cpu_intc: cpu_intc { |
@@ -246,8 +244,6 @@ | |||
246 | interrupts = <86>; | 244 | interrupts = <86>; |
247 | #address-cells = <1>; | 245 | #address-cells = <1>; |
248 | #size-cells = <0>; | 246 | #size-cells = <0>; |
249 | brcm,broken-ncq; | ||
250 | brcm,broken-phy; | ||
251 | status = "disabled"; | 247 | status = "disabled"; |
252 | 248 | ||
253 | sata0: sata-port@0 { | 249 | sata0: sata-port@0 { |
@@ -261,7 +257,7 @@ | |||
261 | }; | 257 | }; |
262 | }; | 258 | }; |
263 | 259 | ||
264 | sata_phy: sata-phy@1800000 { | 260 | sata_phy: sata-phy@180100 { |
265 | compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; | 261 | compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; |
266 | reg = <0x180100 0x0eff>; | 262 | reg = <0x180100 0x0eff>; |
267 | reg-names = "phy"; | 263 | reg-names = "phy"; |
diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi index 3302a1b8a5c9..0586bf662571 100644 --- a/arch/mips/boot/dts/brcm/bcm7420.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi | |||
@@ -86,14 +86,15 @@ | |||
86 | compatible = "brcm,bcm7120-l2-intc"; | 86 | compatible = "brcm,bcm7120-l2-intc"; |
87 | reg = <0x406780 0x8>; | 87 | reg = <0x406780 0x8>; |
88 | 88 | ||
89 | brcm,int-map-mask = <0x44>; | 89 | brcm,int-map-mask = <0x44>, <0x1f000000>; |
90 | brcm,int-fwd-mask = <0x70000>; | 90 | brcm,int-fwd-mask = <0x70000>; |
91 | 91 | ||
92 | interrupt-controller; | 92 | interrupt-controller; |
93 | #interrupt-cells = <1>; | 93 | #interrupt-cells = <1>; |
94 | 94 | ||
95 | interrupt-parent = <&periph_intc>; | 95 | interrupt-parent = <&periph_intc>; |
96 | interrupts = <18>; | 96 | interrupts = <18>, <19>; |
97 | interrupt-names = "upg_main", "upg_bsc"; | ||
97 | }; | 98 | }; |
98 | 99 | ||
99 | sun_top_ctrl: syscon@404000 { | 100 | sun_top_ctrl: syscon@404000 { |
@@ -118,6 +119,78 @@ | |||
118 | status = "disabled"; | 119 | status = "disabled"; |
119 | }; | 120 | }; |
120 | 121 | ||
122 | uart1: serial@406b40 { | ||
123 | compatible = "ns16550a"; | ||
124 | reg = <0x406b40 0x20>; | ||
125 | reg-io-width = <0x4>; | ||
126 | reg-shift = <0x2>; | ||
127 | interrupt-parent = <&periph_intc>; | ||
128 | interrupts = <64>; | ||
129 | clocks = <&uart_clk>; | ||
130 | status = "disabled"; | ||
131 | }; | ||
132 | |||
133 | uart2: serial@406b80 { | ||
134 | compatible = "ns16550a"; | ||
135 | reg = <0x406b80 0x20>; | ||
136 | reg-io-width = <0x4>; | ||
137 | reg-shift = <0x2>; | ||
138 | interrupt-parent = <&periph_intc>; | ||
139 | interrupts = <65>; | ||
140 | clocks = <&uart_clk>; | ||
141 | status = "disabled"; | ||
142 | }; | ||
143 | |||
144 | bsca: i2c@406200 { | ||
145 | clock-frequency = <390000>; | ||
146 | compatible = "brcm,brcmstb-i2c"; | ||
147 | interrupt-parent = <&upg_irq0_intc>; | ||
148 | reg = <0x406200 0x58>; | ||
149 | interrupts = <24>; | ||
150 | interrupt-names = "upg_bsca"; | ||
151 | status = "disabled"; | ||
152 | }; | ||
153 | |||
154 | bscb: i2c@406280 { | ||
155 | clock-frequency = <390000>; | ||
156 | compatible = "brcm,brcmstb-i2c"; | ||
157 | interrupt-parent = <&upg_irq0_intc>; | ||
158 | reg = <0x406280 0x58>; | ||
159 | interrupts = <25>; | ||
160 | interrupt-names = "upg_bscb"; | ||
161 | status = "disabled"; | ||
162 | }; | ||
163 | |||
164 | bscc: i2c@406300 { | ||
165 | clock-frequency = <390000>; | ||
166 | compatible = "brcm,brcmstb-i2c"; | ||
167 | interrupt-parent = <&upg_irq0_intc>; | ||
168 | reg = <0x406300 0x58>; | ||
169 | interrupts = <26>; | ||
170 | interrupt-names = "upg_bscc"; | ||
171 | status = "disabled"; | ||
172 | }; | ||
173 | |||
174 | bscd: i2c@406380 { | ||
175 | clock-frequency = <390000>; | ||
176 | compatible = "brcm,brcmstb-i2c"; | ||
177 | interrupt-parent = <&upg_irq0_intc>; | ||
178 | reg = <0x406380 0x58>; | ||
179 | interrupts = <27>; | ||
180 | interrupt-names = "upg_bscd"; | ||
181 | status = "disabled"; | ||
182 | }; | ||
183 | |||
184 | bsce: i2c@406800 { | ||
185 | clock-frequency = <390000>; | ||
186 | compatible = "brcm,brcmstb-i2c"; | ||
187 | interrupt-parent = <&upg_irq0_intc>; | ||
188 | reg = <0x406800 0x58>; | ||
189 | interrupts = <28>; | ||
190 | interrupt-names = "upg_bsce"; | ||
191 | status = "disabled"; | ||
192 | }; | ||
193 | |||
121 | enet0: ethernet@468000 { | 194 | enet0: ethernet@468000 { |
122 | phy-mode = "internal"; | 195 | phy-mode = "internal"; |
123 | phy-handle = <&phy1>; | 196 | phy-handle = <&phy1>; |
diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index 15b27aae15a9..c1c15edaf829 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi | |||
@@ -87,14 +87,32 @@ | |||
87 | compatible = "brcm,bcm7120-l2-intc"; | 87 | compatible = "brcm,bcm7120-l2-intc"; |
88 | reg = <0x406780 0x8>; | 88 | reg = <0x406780 0x8>; |
89 | 89 | ||
90 | brcm,int-map-mask = <0x44>; | 90 | brcm,int-map-mask = <0x44>, <0x7000000>; |
91 | brcm,int-fwd-mask = <0x70000>; | 91 | brcm,int-fwd-mask = <0x70000>; |
92 | 92 | ||
93 | interrupt-controller; | 93 | interrupt-controller; |
94 | #interrupt-cells = <1>; | 94 | #interrupt-cells = <1>; |
95 | 95 | ||
96 | interrupt-parent = <&periph_intc>; | 96 | interrupt-parent = <&periph_intc>; |
97 | interrupts = <55>; | 97 | interrupts = <55>, <53>; |
98 | interrupt-names = "upg_main", "upg_bsc"; | ||
99 | }; | ||
100 | |||
101 | upg_aon_irq0_intc: upg_aon_irq0_intc@409480 { | ||
102 | compatible = "brcm,bcm7120-l2-intc"; | ||
103 | reg = <0x409480 0x8>; | ||
104 | |||
105 | brcm,int-map-mask = <0x40>, <0x18000000>, <0x100000>; | ||
106 | brcm,int-fwd-mask = <0>; | ||
107 | brcm,irq-can-wake; | ||
108 | |||
109 | interrupt-controller; | ||
110 | #interrupt-cells = <1>; | ||
111 | |||
112 | interrupt-parent = <&periph_intc>; | ||
113 | interrupts = <56>, <54>, <59>; | ||
114 | interrupt-names = "upg_main_aon", "upg_bsc_aon", | ||
115 | "upg_spi"; | ||
98 | }; | 116 | }; |
99 | 117 | ||
100 | sun_top_ctrl: syscon@404000 { | 118 | sun_top_ctrl: syscon@404000 { |
@@ -119,6 +137,78 @@ | |||
119 | status = "disabled"; | 137 | status = "disabled"; |
120 | }; | 138 | }; |
121 | 139 | ||
140 | uart1: serial@406b40 { | ||
141 | compatible = "ns16550a"; | ||
142 | reg = <0x406b40 0x20>; | ||
143 | reg-io-width = <0x4>; | ||
144 | reg-shift = <0x2>; | ||
145 | interrupt-parent = <&periph_intc>; | ||
146 | interrupts = <62>; | ||
147 | clocks = <&uart_clk>; | ||
148 | status = "disabled"; | ||
149 | }; | ||
150 | |||
151 | uart2: serial@406b80 { | ||
152 | compatible = "ns16550a"; | ||
153 | reg = <0x406b80 0x20>; | ||
154 | reg-io-width = <0x4>; | ||
155 | reg-shift = <0x2>; | ||
156 | interrupt-parent = <&periph_intc>; | ||
157 | interrupts = <63>; | ||
158 | clocks = <&uart_clk>; | ||
159 | status = "disabled"; | ||
160 | }; | ||
161 | |||
162 | bsca: i2c@409180 { | ||
163 | clock-frequency = <390000>; | ||
164 | compatible = "brcm,brcmstb-i2c"; | ||
165 | interrupt-parent = <&upg_aon_irq0_intc>; | ||
166 | reg = <0x409180 0x58>; | ||
167 | interrupts = <27>; | ||
168 | interrupt-names = "upg_bsca"; | ||
169 | status = "disabled"; | ||
170 | }; | ||
171 | |||
172 | bscb: i2c@409400 { | ||
173 | clock-frequency = <390000>; | ||
174 | compatible = "brcm,brcmstb-i2c"; | ||
175 | interrupt-parent = <&upg_aon_irq0_intc>; | ||
176 | reg = <0x409400 0x58>; | ||
177 | interrupts = <28>; | ||
178 | interrupt-names = "upg_bscb"; | ||
179 | status = "disabled"; | ||
180 | }; | ||
181 | |||
182 | bscc: i2c@406200 { | ||
183 | clock-frequency = <390000>; | ||
184 | compatible = "brcm,brcmstb-i2c"; | ||
185 | interrupt-parent = <&upg_irq0_intc>; | ||
186 | reg = <0x406200 0x58>; | ||
187 | interrupts = <24>; | ||
188 | interrupt-names = "upg_bscc"; | ||
189 | status = "disabled"; | ||
190 | }; | ||
191 | |||
192 | bscd: i2c@406280 { | ||
193 | clock-frequency = <390000>; | ||
194 | compatible = "brcm,brcmstb-i2c"; | ||
195 | interrupt-parent = <&upg_irq0_intc>; | ||
196 | reg = <0x406280 0x58>; | ||
197 | interrupts = <25>; | ||
198 | interrupt-names = "upg_bscd"; | ||
199 | status = "disabled"; | ||
200 | }; | ||
201 | |||
202 | bsce: i2c@406300 { | ||
203 | clock-frequency = <390000>; | ||
204 | compatible = "brcm,brcmstb-i2c"; | ||
205 | interrupt-parent = <&upg_irq0_intc>; | ||
206 | reg = <0x406300 0x58>; | ||
207 | interrupts = <26>; | ||
208 | interrupt-names = "upg_bsce"; | ||
209 | status = "disabled"; | ||
210 | }; | ||
211 | |||
122 | enet0: ethernet@b80000 { | 212 | enet0: ethernet@b80000 { |
123 | phy-mode = "internal"; | 213 | phy-mode = "internal"; |
124 | phy-handle = <&phy1>; | 214 | phy-handle = <&phy1>; |
@@ -227,11 +317,9 @@ | |||
227 | reg-names = "ahci", "top-ctrl"; | 317 | reg-names = "ahci", "top-ctrl"; |
228 | reg = <0x181000 0xa9c>, <0x180020 0x1c>; | 318 | reg = <0x181000 0xa9c>, <0x180020 0x1c>; |
229 | interrupt-parent = <&periph_intc>; | 319 | interrupt-parent = <&periph_intc>; |
230 | interrupts = <40>; | 320 | interrupts = <41>; |
231 | #address-cells = <1>; | 321 | #address-cells = <1>; |
232 | #size-cells = <0>; | 322 | #size-cells = <0>; |
233 | brcm,broken-ncq; | ||
234 | brcm,broken-phy; | ||
235 | status = "disabled"; | 323 | status = "disabled"; |
236 | 324 | ||
237 | sata0: sata-port@0 { | 325 | sata0: sata-port@0 { |
@@ -245,7 +333,7 @@ | |||
245 | }; | 333 | }; |
246 | }; | 334 | }; |
247 | 335 | ||
248 | sata_phy: sata-phy@1800000 { | 336 | sata_phy: sata-phy@180100 { |
249 | compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; | 337 | compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; |
250 | reg = <0x180100 0x0eff>; | 338 | reg = <0x180100 0x0eff>; |
251 | reg-names = "phy"; | 339 | reg-names = "phy"; |
diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index 56035e5b7008..a874d3a0e2ee 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi | |||
@@ -7,7 +7,7 @@ | |||
7 | #address-cells = <1>; | 7 | #address-cells = <1>; |
8 | #size-cells = <0>; | 8 | #size-cells = <0>; |
9 | 9 | ||
10 | mips-hpt-frequency = <163125000>; | 10 | mips-hpt-frequency = <175625000>; |
11 | 11 | ||
12 | cpu@0 { | 12 | cpu@0 { |
13 | compatible = "brcm,bmips5200"; | 13 | compatible = "brcm,bmips5200"; |
@@ -63,13 +63,14 @@ | |||
63 | 63 | ||
64 | periph_intc: periph_intc@41b500 { | 64 | periph_intc: periph_intc@41b500 { |
65 | compatible = "brcm,bcm7038-l1-intc"; | 65 | compatible = "brcm,bcm7038-l1-intc"; |
66 | reg = <0x41b500 0x40>, <0x41b600 0x40>; | 66 | reg = <0x41b500 0x40>, <0x41b600 0x40>, |
67 | <0x41b700 0x40>, <0x41b800 0x40>; | ||
67 | 68 | ||
68 | interrupt-controller; | 69 | interrupt-controller; |
69 | #interrupt-cells = <1>; | 70 | #interrupt-cells = <1>; |
70 | 71 | ||
71 | interrupt-parent = <&cpu_intc>; | 72 | interrupt-parent = <&cpu_intc>; |
72 | interrupts = <2>, <3>; | 73 | interrupts = <2>, <3>, <2>, <3>; |
73 | }; | 74 | }; |
74 | 75 | ||
75 | sun_l2_intc: sun_l2_intc@403000 { | 76 | sun_l2_intc: sun_l2_intc@403000 { |
@@ -101,14 +102,32 @@ | |||
101 | compatible = "brcm,bcm7120-l2-intc"; | 102 | compatible = "brcm,bcm7120-l2-intc"; |
102 | reg = <0x406780 0x8>; | 103 | reg = <0x406780 0x8>; |
103 | 104 | ||
104 | brcm,int-map-mask = <0x44>; | 105 | brcm,int-map-mask = <0x44>, <0x7000000>; |
105 | brcm,int-fwd-mask = <0x70000>; | 106 | brcm,int-fwd-mask = <0x70000>; |
106 | 107 | ||
107 | interrupt-controller; | 108 | interrupt-controller; |
108 | #interrupt-cells = <1>; | 109 | #interrupt-cells = <1>; |
109 | 110 | ||
110 | interrupt-parent = <&periph_intc>; | 111 | interrupt-parent = <&periph_intc>; |
111 | interrupts = <60>; | 112 | interrupts = <60>, <58>; |
113 | interrupt-names = "upg_main", "upg_bsc"; | ||
114 | }; | ||
115 | |||
116 | upg_aon_irq0_intc: upg_aon_irq0_intc@409480 { | ||
117 | compatible = "brcm,bcm7120-l2-intc"; | ||
118 | reg = <0x409480 0x8>; | ||
119 | |||
120 | brcm,int-map-mask = <0x40>, <0x18000000>, <0x100000>; | ||
121 | brcm,int-fwd-mask = <0>; | ||
122 | brcm,irq-can-wake; | ||
123 | |||
124 | interrupt-controller; | ||
125 | #interrupt-cells = <1>; | ||
126 | |||
127 | interrupt-parent = <&periph_intc>; | ||
128 | interrupts = <61>, <59>, <64>; | ||
129 | interrupt-names = "upg_main_aon", "upg_bsc_aon", | ||
130 | "upg_spi"; | ||
112 | }; | 131 | }; |
113 | 132 | ||
114 | sun_top_ctrl: syscon@404000 { | 133 | sun_top_ctrl: syscon@404000 { |
@@ -133,6 +152,78 @@ | |||
133 | status = "disabled"; | 152 | status = "disabled"; |
134 | }; | 153 | }; |
135 | 154 | ||
155 | uart1: serial@406b40 { | ||
156 | compatible = "ns16550a"; | ||
157 | reg = <0x406b40 0x20>; | ||
158 | reg-io-width = <0x4>; | ||
159 | reg-shift = <0x2>; | ||
160 | interrupt-parent = <&periph_intc>; | ||
161 | interrupts = <67>; | ||
162 | clocks = <&uart_clk>; | ||
163 | status = "disabled"; | ||
164 | }; | ||
165 | |||
166 | uart2: serial@406b80 { | ||
167 | compatible = "ns16550a"; | ||
168 | reg = <0x406b80 0x20>; | ||
169 | reg-io-width = <0x4>; | ||
170 | reg-shift = <0x2>; | ||
171 | interrupt-parent = <&periph_intc>; | ||
172 | interrupts = <68>; | ||
173 | clocks = <&uart_clk>; | ||
174 | status = "disabled"; | ||
175 | }; | ||
176 | |||
177 | bsca: i2c@406300 { | ||
178 | clock-frequency = <390000>; | ||
179 | compatible = "brcm,brcmstb-i2c"; | ||
180 | interrupt-parent = <&upg_irq0_intc>; | ||
181 | reg = <0x406300 0x58>; | ||
182 | interrupts = <26>; | ||
183 | interrupt-names = "upg_bsca"; | ||
184 | status = "disabled"; | ||
185 | }; | ||
186 | |||
187 | bscb: i2c@409400 { | ||
188 | clock-frequency = <390000>; | ||
189 | compatible = "brcm,brcmstb-i2c"; | ||
190 | interrupt-parent = <&upg_aon_irq0_intc>; | ||
191 | reg = <0x409400 0x58>; | ||
192 | interrupts = <28>; | ||
193 | interrupt-names = "upg_bscb"; | ||
194 | status = "disabled"; | ||
195 | }; | ||
196 | |||
197 | bscc: i2c@406200 { | ||
198 | clock-frequency = <390000>; | ||
199 | compatible = "brcm,brcmstb-i2c"; | ||
200 | interrupt-parent = <&upg_irq0_intc>; | ||
201 | reg = <0x406200 0x58>; | ||
202 | interrupts = <24>; | ||
203 | interrupt-names = "upg_bscc"; | ||
204 | status = "disabled"; | ||
205 | }; | ||
206 | |||
207 | bscd: i2c@406280 { | ||
208 | clock-frequency = <390000>; | ||
209 | compatible = "brcm,brcmstb-i2c"; | ||
210 | interrupt-parent = <&upg_irq0_intc>; | ||
211 | reg = <0x406280 0x58>; | ||
212 | interrupts = <25>; | ||
213 | interrupt-names = "upg_bscd"; | ||
214 | status = "disabled"; | ||
215 | }; | ||
216 | |||
217 | bsce: i2c@409180 { | ||
218 | clock-frequency = <390000>; | ||
219 | compatible = "brcm,brcmstb-i2c"; | ||
220 | interrupt-parent = <&upg_aon_irq0_intc>; | ||
221 | reg = <0x409180 0x58>; | ||
222 | interrupts = <27>; | ||
223 | interrupt-names = "upg_bsce"; | ||
224 | status = "disabled"; | ||
225 | }; | ||
226 | |||
136 | enet0: ethernet@b80000 { | 227 | enet0: ethernet@b80000 { |
137 | phy-mode = "internal"; | 228 | phy-mode = "internal"; |
138 | phy-handle = <&phy1>; | 229 | phy-handle = <&phy1>; |
@@ -235,5 +326,45 @@ | |||
235 | interrupts = <78>; | 326 | interrupts = <78>; |
236 | status = "disabled"; | 327 | status = "disabled"; |
237 | }; | 328 | }; |
329 | |||
330 | sata: sata@181000 { | ||
331 | compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; | ||
332 | reg-names = "ahci", "top-ctrl"; | ||
333 | reg = <0x181000 0xa9c>, <0x180020 0x1c>; | ||
334 | interrupt-parent = <&periph_intc>; | ||
335 | interrupts = <45>; | ||
336 | #address-cells = <1>; | ||
337 | #size-cells = <0>; | ||
338 | status = "disabled"; | ||
339 | |||
340 | sata0: sata-port@0 { | ||
341 | reg = <0>; | ||
342 | phys = <&sata_phy0>; | ||
343 | }; | ||
344 | |||
345 | sata1: sata-port@1 { | ||
346 | reg = <1>; | ||
347 | phys = <&sata_phy1>; | ||
348 | }; | ||
349 | }; | ||
350 | |||
351 | sata_phy: sata-phy@180100 { | ||
352 | compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; | ||
353 | reg = <0x180100 0x0eff>; | ||
354 | reg-names = "phy"; | ||
355 | #address-cells = <1>; | ||
356 | #size-cells = <0>; | ||
357 | status = "disabled"; | ||
358 | |||
359 | sata_phy0: sata-phy@0 { | ||
360 | reg = <0>; | ||
361 | #phy-cells = <0>; | ||
362 | }; | ||
363 | |||
364 | sata_phy1: sata-phy@1 { | ||
365 | reg = <1>; | ||
366 | #phy-cells = <0>; | ||
367 | }; | ||
368 | }; | ||
238 | }; | 369 | }; |
239 | }; | 370 | }; |
diff --git a/arch/mips/boot/dts/brcm/bcm96358nb4ser.dts b/arch/mips/boot/dts/brcm/bcm96358nb4ser.dts new file mode 100644 index 000000000000..f412117972e6 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm96358nb4ser.dts | |||
@@ -0,0 +1,46 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "bcm6358.dtsi" | ||
4 | |||
5 | / { | ||
6 | compatible = "sfr,nb4-ser", "brcm,bcm6358"; | ||
7 | model = "SFR Neufbox 4 (Sercomm)"; | ||
8 | |||
9 | memory@0 { | ||
10 | device_type = "memory"; | ||
11 | reg = <0x00000000 0x02000000>; | ||
12 | }; | ||
13 | |||
14 | chosen { | ||
15 | stdout-path = &uart0; | ||
16 | }; | ||
17 | }; | ||
18 | |||
19 | &leds0 { | ||
20 | status = "ok"; | ||
21 | |||
22 | led@0 { | ||
23 | reg = <0>; | ||
24 | active-low; | ||
25 | label = "nb4-ser:white:alarm"; | ||
26 | }; | ||
27 | led@2 { | ||
28 | reg = <2>; | ||
29 | active-low; | ||
30 | label = "nb4-ser:white:tv"; | ||
31 | }; | ||
32 | led@3 { | ||
33 | reg = <3>; | ||
34 | active-low; | ||
35 | label = "nb4-ser:white:tel"; | ||
36 | }; | ||
37 | led@4 { | ||
38 | reg = <4>; | ||
39 | active-low; | ||
40 | label = "nb4-ser:white:adsl"; | ||
41 | }; | ||
42 | }; | ||
43 | |||
44 | &uart0 { | ||
45 | status = "okay"; | ||
46 | }; | ||
diff --git a/arch/mips/boot/dts/brcm/bcm96368mvwg.dts b/arch/mips/boot/dts/brcm/bcm96368mvwg.dts index 0e890c28fe5c..8c71c6845730 100644 --- a/arch/mips/boot/dts/brcm/bcm96368mvwg.dts +++ b/arch/mips/boot/dts/brcm/bcm96368mvwg.dts | |||
@@ -22,10 +22,10 @@ | |||
22 | }; | 22 | }; |
23 | 23 | ||
24 | /* FIXME: need to set up USB_CTRL registers first */ | 24 | /* FIXME: need to set up USB_CTRL registers first */ |
25 | &ehci0 { | 25 | &ehci { |
26 | status = "disabled"; | 26 | status = "disabled"; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | &ohci0 { | 29 | &ohci { |
30 | status = "disabled"; | 30 | status = "disabled"; |
31 | }; | 31 | }; |
diff --git a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts index e046b1109eab..f2449d147c6d 100644 --- a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts | |||
@@ -21,6 +21,30 @@ | |||
21 | status = "okay"; | 21 | status = "okay"; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | &uart1 { | ||
25 | status = "okay"; | ||
26 | }; | ||
27 | |||
28 | &uart2 { | ||
29 | status = "okay"; | ||
30 | }; | ||
31 | |||
32 | &bsca { | ||
33 | status = "okay"; | ||
34 | }; | ||
35 | |||
36 | &bscb { | ||
37 | status = "okay"; | ||
38 | }; | ||
39 | |||
40 | &bscc { | ||
41 | status = "okay"; | ||
42 | }; | ||
43 | |||
44 | &bscd { | ||
45 | status = "okay"; | ||
46 | }; | ||
47 | |||
24 | /* FIXME: USB is wonky; disable it for now */ | 48 | /* FIXME: USB is wonky; disable it for now */ |
25 | &ehci0 { | 49 | &ehci0 { |
26 | status = "disabled"; | 50 | status = "disabled"; |
diff --git a/arch/mips/boot/dts/brcm/bcm97360svmb.dts b/arch/mips/boot/dts/brcm/bcm97360svmb.dts index d48462e091f1..73124be9548a 100644 --- a/arch/mips/boot/dts/brcm/bcm97360svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97360svmb.dts | |||
@@ -56,3 +56,11 @@ | |||
56 | &ohci0 { | 56 | &ohci0 { |
57 | status = "okay"; | 57 | status = "okay"; |
58 | }; | 58 | }; |
59 | |||
60 | &sata { | ||
61 | status = "okay"; | ||
62 | }; | ||
63 | |||
64 | &sata_phy { | ||
65 | status = "okay"; | ||
66 | }; | ||
diff --git a/arch/mips/boot/dts/brcm/bcm97420c.dts b/arch/mips/boot/dts/brcm/bcm97420c.dts index 67fe1f3a3891..600d57abee05 100644 --- a/arch/mips/boot/dts/brcm/bcm97420c.dts +++ b/arch/mips/boot/dts/brcm/bcm97420c.dts | |||
@@ -23,6 +23,34 @@ | |||
23 | status = "okay"; | 23 | status = "okay"; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | &uart1 { | ||
27 | status = "okay"; | ||
28 | }; | ||
29 | |||
30 | &uart2 { | ||
31 | status = "okay"; | ||
32 | }; | ||
33 | |||
34 | &bsca { | ||
35 | status = "okay"; | ||
36 | }; | ||
37 | |||
38 | &bscb { | ||
39 | status = "okay"; | ||
40 | }; | ||
41 | |||
42 | &bscc { | ||
43 | status = "okay"; | ||
44 | }; | ||
45 | |||
46 | &bscd { | ||
47 | status = "okay"; | ||
48 | }; | ||
49 | |||
50 | &bsce { | ||
51 | status = "okay"; | ||
52 | }; | ||
53 | |||
26 | /* FIXME: MAC driver comes up but cannot attach to PHY */ | 54 | /* FIXME: MAC driver comes up but cannot attach to PHY */ |
27 | &enet0 { | 55 | &enet0 { |
28 | status = "disabled"; | 56 | status = "disabled"; |
diff --git a/arch/mips/boot/dts/brcm/bcm97425svmb.dts b/arch/mips/boot/dts/brcm/bcm97425svmb.dts index 689c68a4f9c8..119c714805cb 100644 --- a/arch/mips/boot/dts/brcm/bcm97425svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97425svmb.dts | |||
@@ -23,6 +23,34 @@ | |||
23 | status = "okay"; | 23 | status = "okay"; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | &uart1 { | ||
27 | status = "okay"; | ||
28 | }; | ||
29 | |||
30 | &uart2 { | ||
31 | status = "okay"; | ||
32 | }; | ||
33 | |||
34 | &bsca { | ||
35 | status = "okay"; | ||
36 | }; | ||
37 | |||
38 | &bscb { | ||
39 | status = "okay"; | ||
40 | }; | ||
41 | |||
42 | &bscc { | ||
43 | status = "okay"; | ||
44 | }; | ||
45 | |||
46 | &bscd { | ||
47 | status = "okay"; | ||
48 | }; | ||
49 | |||
50 | &bsce { | ||
51 | status = "okay"; | ||
52 | }; | ||
53 | |||
26 | &enet0 { | 54 | &enet0 { |
27 | status = "okay"; | 55 | status = "okay"; |
28 | }; | 56 | }; |
diff --git a/arch/mips/boot/dts/brcm/bcm97435svmb.dts b/arch/mips/boot/dts/brcm/bcm97435svmb.dts index 1df088183523..43e3ba27f07b 100644 --- a/arch/mips/boot/dts/brcm/bcm97435svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97435svmb.dts | |||
@@ -14,7 +14,7 @@ | |||
14 | }; | 14 | }; |
15 | 15 | ||
16 | chosen { | 16 | chosen { |
17 | bootargs = "console=ttyS0,115200 maxcpus=1"; | 17 | bootargs = "console=ttyS0,115200"; |
18 | stdout-path = &uart0; | 18 | stdout-path = &uart0; |
19 | }; | 19 | }; |
20 | }; | 20 | }; |
@@ -23,6 +23,34 @@ | |||
23 | status = "okay"; | 23 | status = "okay"; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | &uart1 { | ||
27 | status = "okay"; | ||
28 | }; | ||
29 | |||
30 | &uart2 { | ||
31 | status = "okay"; | ||
32 | }; | ||
33 | |||
34 | &bsca { | ||
35 | status = "okay"; | ||
36 | }; | ||
37 | |||
38 | &bscb { | ||
39 | status = "okay"; | ||
40 | }; | ||
41 | |||
42 | &bscc { | ||
43 | status = "okay"; | ||
44 | }; | ||
45 | |||
46 | &bscd { | ||
47 | status = "okay"; | ||
48 | }; | ||
49 | |||
50 | &bsce { | ||
51 | status = "okay"; | ||
52 | }; | ||
53 | |||
26 | &enet0 { | 54 | &enet0 { |
27 | status = "okay"; | 55 | status = "okay"; |
28 | }; | 56 | }; |
@@ -58,3 +86,11 @@ | |||
58 | &ohci3 { | 86 | &ohci3 { |
59 | status = "okay"; | 87 | status = "okay"; |
60 | }; | 88 | }; |
89 | |||
90 | &sata { | ||
91 | status = "okay"; | ||
92 | }; | ||
93 | |||
94 | &sata_phy { | ||
95 | status = "okay"; | ||
96 | }; | ||
diff --git a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts new file mode 100644 index 000000000000..d6bc994f736f --- /dev/null +++ b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * Device tree source for D-Link DSR-1000N. | ||
3 | * | ||
4 | * Written by: Aaro Koskinen <aaro.koskinen@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | /include/ "octeon_3xxx.dtsi" | ||
12 | |||
13 | / { | ||
14 | model = "dlink,dsr-1000n"; | ||
15 | |||
16 | soc@0 { | ||
17 | smi0: mdio@1180000001800 { | ||
18 | phy8: ethernet-phy@8 { | ||
19 | reg = <8>; | ||
20 | compatible = "ethernet-phy-ieee802.3-c22"; | ||
21 | }; | ||
22 | }; | ||
23 | |||
24 | pip: pip@11800a0000000 { | ||
25 | interface@0 { | ||
26 | ethernet@0 { | ||
27 | fixed-link { | ||
28 | speed = <1000>; | ||
29 | full-duplex; | ||
30 | }; | ||
31 | }; | ||
32 | ethernet@1 { | ||
33 | fixed-link { | ||
34 | speed = <1000>; | ||
35 | full-duplex; | ||
36 | }; | ||
37 | }; | ||
38 | ethernet@2 { | ||
39 | phy-handle = <&phy8>; | ||
40 | }; | ||
41 | }; | ||
42 | }; | ||
43 | |||
44 | twsi0: i2c@1180000001000 { | ||
45 | rtc@68 { | ||
46 | compatible = "dallas,ds1337"; | ||
47 | reg = <0x68>; | ||
48 | }; | ||
49 | }; | ||
50 | |||
51 | uart0: serial@1180000000800 { | ||
52 | clock-frequency = <500000000>; | ||
53 | }; | ||
54 | |||
55 | usbn: usbn@1180068000000 { | ||
56 | refclk-frequency = <12000000>; | ||
57 | refclk-type = "crystal"; | ||
58 | }; | ||
59 | }; | ||
60 | |||
61 | leds { | ||
62 | compatible = "gpio-leds"; | ||
63 | |||
64 | usb1 { | ||
65 | label = "usb1"; | ||
66 | gpios = <&gpio 9 1>; /* Active low */ | ||
67 | }; | ||
68 | |||
69 | usb2 { | ||
70 | label = "usb2"; | ||
71 | gpios = <&gpio 10 1>; /* Active low */ | ||
72 | }; | ||
73 | }; | ||
74 | |||
75 | aliases { | ||
76 | pip = &pip; | ||
77 | }; | ||
78 | }; | ||
diff --git a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts index 9c48e0586ba7..de61f02d3ef6 100644 --- a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts +++ b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts | |||
@@ -1,4 +1,3 @@ | |||
1 | /dts-v1/; | ||
2 | /* | 1 | /* |
3 | * OCTEON 3XXX, 5XXX, 63XX device tree skeleton. | 2 | * OCTEON 3XXX, 5XXX, 63XX device tree skeleton. |
4 | * | 3 | * |
@@ -6,56 +5,12 @@ | |||
6 | * use. Because of this, it contains a super-set of the available | 5 | * use. Because of this, it contains a super-set of the available |
7 | * devices and properties. | 6 | * devices and properties. |
8 | */ | 7 | */ |
9 | / { | ||
10 | compatible = "cavium,octeon-3860"; | ||
11 | #address-cells = <2>; | ||
12 | #size-cells = <2>; | ||
13 | interrupt-parent = <&ciu>; | ||
14 | |||
15 | soc@0 { | ||
16 | compatible = "simple-bus"; | ||
17 | #address-cells = <2>; | ||
18 | #size-cells = <2>; | ||
19 | ranges; /* Direct mapping */ | ||
20 | |||
21 | ciu: interrupt-controller@1070000000000 { | ||
22 | compatible = "cavium,octeon-3860-ciu"; | ||
23 | interrupt-controller; | ||
24 | /* Interrupts are specified by two parts: | ||
25 | * 1) Controller register (0 or 1) | ||
26 | * 2) Bit within the register (0..63) | ||
27 | */ | ||
28 | #interrupt-cells = <2>; | ||
29 | reg = <0x10700 0x00000000 0x0 0x7000>; | ||
30 | }; | ||
31 | 8 | ||
32 | gpio: gpio-controller@1070000000800 { | 9 | /include/ "octeon_3xxx.dtsi" |
33 | #gpio-cells = <2>; | ||
34 | compatible = "cavium,octeon-3860-gpio"; | ||
35 | reg = <0x10700 0x00000800 0x0 0x100>; | ||
36 | gpio-controller; | ||
37 | /* Interrupts are specified by two parts: | ||
38 | * 1) GPIO pin number (0..15) | ||
39 | * 2) Triggering (1 - edge rising | ||
40 | * 2 - edge falling | ||
41 | * 4 - level active high | ||
42 | * 8 - level active low) | ||
43 | */ | ||
44 | interrupt-controller; | ||
45 | #interrupt-cells = <2>; | ||
46 | /* The GPIO pin connect to 16 consecutive CUI bits */ | ||
47 | interrupts = <0 16>, <0 17>, <0 18>, <0 19>, | ||
48 | <0 20>, <0 21>, <0 22>, <0 23>, | ||
49 | <0 24>, <0 25>, <0 26>, <0 27>, | ||
50 | <0 28>, <0 29>, <0 30>, <0 31>; | ||
51 | }; | ||
52 | 10 | ||
11 | / { | ||
12 | soc@0 { | ||
53 | smi0: mdio@1180000001800 { | 13 | smi0: mdio@1180000001800 { |
54 | compatible = "cavium,octeon-3860-mdio"; | ||
55 | #address-cells = <1>; | ||
56 | #size-cells = <0>; | ||
57 | reg = <0x11800 0x00001800 0x0 0x40>; | ||
58 | |||
59 | phy0: ethernet-phy@0 { | 14 | phy0: ethernet-phy@0 { |
60 | compatible = "marvell,88e1118"; | 15 | compatible = "marvell,88e1118"; |
61 | marvell,reg-init = | 16 | marvell,reg-init = |
@@ -220,35 +175,16 @@ | |||
220 | }; | 175 | }; |
221 | 176 | ||
222 | pip: pip@11800a0000000 { | 177 | pip: pip@11800a0000000 { |
223 | compatible = "cavium,octeon-3860-pip"; | ||
224 | #address-cells = <1>; | ||
225 | #size-cells = <0>; | ||
226 | reg = <0x11800 0xa0000000 0x0 0x2000>; | ||
227 | |||
228 | interface@0 { | 178 | interface@0 { |
229 | compatible = "cavium,octeon-3860-pip-interface"; | ||
230 | #address-cells = <1>; | ||
231 | #size-cells = <0>; | ||
232 | reg = <0>; /* interface */ | ||
233 | |||
234 | ethernet@0 { | 179 | ethernet@0 { |
235 | compatible = "cavium,octeon-3860-pip-port"; | ||
236 | reg = <0x0>; /* Port */ | ||
237 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
238 | phy-handle = <&phy2>; | 180 | phy-handle = <&phy2>; |
239 | cavium,alt-phy-handle = <&phy100>; | 181 | cavium,alt-phy-handle = <&phy100>; |
240 | }; | 182 | }; |
241 | ethernet@1 { | 183 | ethernet@1 { |
242 | compatible = "cavium,octeon-3860-pip-port"; | ||
243 | reg = <0x1>; /* Port */ | ||
244 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
245 | phy-handle = <&phy3>; | 184 | phy-handle = <&phy3>; |
246 | cavium,alt-phy-handle = <&phy101>; | 185 | cavium,alt-phy-handle = <&phy101>; |
247 | }; | 186 | }; |
248 | ethernet@2 { | 187 | ethernet@2 { |
249 | compatible = "cavium,octeon-3860-pip-port"; | ||
250 | reg = <0x2>; /* Port */ | ||
251 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
252 | phy-handle = <&phy4>; | 188 | phy-handle = <&phy4>; |
253 | cavium,alt-phy-handle = <&phy102>; | 189 | cavium,alt-phy-handle = <&phy102>; |
254 | }; | 190 | }; |
@@ -322,11 +258,6 @@ | |||
322 | }; | 258 | }; |
323 | 259 | ||
324 | interface@1 { | 260 | interface@1 { |
325 | compatible = "cavium,octeon-3860-pip-interface"; | ||
326 | #address-cells = <1>; | ||
327 | #size-cells = <0>; | ||
328 | reg = <1>; /* interface */ | ||
329 | |||
330 | ethernet@0 { | 261 | ethernet@0 { |
331 | compatible = "cavium,octeon-3860-pip-port"; | 262 | compatible = "cavium,octeon-3860-pip-port"; |
332 | reg = <0x0>; /* Port */ | 263 | reg = <0x0>; /* Port */ |
@@ -355,13 +286,6 @@ | |||
355 | }; | 286 | }; |
356 | 287 | ||
357 | twsi0: i2c@1180000001000 { | 288 | twsi0: i2c@1180000001000 { |
358 | #address-cells = <1>; | ||
359 | #size-cells = <0>; | ||
360 | compatible = "cavium,octeon-3860-twsi"; | ||
361 | reg = <0x11800 0x00001000 0x0 0x200>; | ||
362 | interrupts = <0 45>; | ||
363 | clock-frequency = <100000>; | ||
364 | |||
365 | rtc@68 { | 289 | rtc@68 { |
366 | compatible = "dallas,ds1337"; | 290 | compatible = "dallas,ds1337"; |
367 | reg = <0x68>; | 291 | reg = <0x68>; |
@@ -381,15 +305,6 @@ | |||
381 | clock-frequency = <100000>; | 305 | clock-frequency = <100000>; |
382 | }; | 306 | }; |
383 | 307 | ||
384 | uart0: serial@1180000000800 { | ||
385 | compatible = "cavium,octeon-3860-uart","ns16550"; | ||
386 | reg = <0x11800 0x00000800 0x0 0x400>; | ||
387 | clock-frequency = <0>; | ||
388 | current-speed = <115200>; | ||
389 | reg-shift = <3>; | ||
390 | interrupts = <0 34>; | ||
391 | }; | ||
392 | |||
393 | uart1: serial@1180000000c00 { | 308 | uart1: serial@1180000000c00 { |
394 | compatible = "cavium,octeon-3860-uart","ns16550"; | 309 | compatible = "cavium,octeon-3860-uart","ns16550"; |
395 | reg = <0x11800 0x00000c00 0x0 0x400>; | 310 | reg = <0x11800 0x00000c00 0x0 0x400>; |
@@ -409,98 +324,6 @@ | |||
409 | }; | 324 | }; |
410 | 325 | ||
411 | bootbus: bootbus@1180000000000 { | 326 | bootbus: bootbus@1180000000000 { |
412 | compatible = "cavium,octeon-3860-bootbus"; | ||
413 | reg = <0x11800 0x00000000 0x0 0x200>; | ||
414 | /* The chip select number and offset */ | ||
415 | #address-cells = <2>; | ||
416 | /* The size of the chip select region */ | ||
417 | #size-cells = <1>; | ||
418 | ranges = <0 0 0x0 0x1f400000 0xc00000>, | ||
419 | <1 0 0x10000 0x30000000 0>, | ||
420 | <2 0 0x10000 0x40000000 0>, | ||
421 | <3 0 0x10000 0x50000000 0>, | ||
422 | <4 0 0x0 0x1d020000 0x10000>, | ||
423 | <5 0 0x0 0x1d040000 0x10000>, | ||
424 | <6 0 0x0 0x1d050000 0x10000>, | ||
425 | <7 0 0x10000 0x90000000 0>; | ||
426 | |||
427 | cavium,cs-config@0 { | ||
428 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
429 | cavium,cs-index = <0>; | ||
430 | cavium,t-adr = <20>; | ||
431 | cavium,t-ce = <60>; | ||
432 | cavium,t-oe = <60>; | ||
433 | cavium,t-we = <45>; | ||
434 | cavium,t-rd-hld = <35>; | ||
435 | cavium,t-wr-hld = <45>; | ||
436 | cavium,t-pause = <0>; | ||
437 | cavium,t-wait = <0>; | ||
438 | cavium,t-page = <35>; | ||
439 | cavium,t-rd-dly = <0>; | ||
440 | |||
441 | cavium,pages = <0>; | ||
442 | cavium,bus-width = <8>; | ||
443 | }; | ||
444 | cavium,cs-config@4 { | ||
445 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
446 | cavium,cs-index = <4>; | ||
447 | cavium,t-adr = <320>; | ||
448 | cavium,t-ce = <320>; | ||
449 | cavium,t-oe = <320>; | ||
450 | cavium,t-we = <320>; | ||
451 | cavium,t-rd-hld = <320>; | ||
452 | cavium,t-wr-hld = <320>; | ||
453 | cavium,t-pause = <320>; | ||
454 | cavium,t-wait = <320>; | ||
455 | cavium,t-page = <320>; | ||
456 | cavium,t-rd-dly = <0>; | ||
457 | |||
458 | cavium,pages = <0>; | ||
459 | cavium,bus-width = <8>; | ||
460 | }; | ||
461 | cavium,cs-config@5 { | ||
462 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
463 | cavium,cs-index = <5>; | ||
464 | cavium,t-adr = <5>; | ||
465 | cavium,t-ce = <300>; | ||
466 | cavium,t-oe = <125>; | ||
467 | cavium,t-we = <150>; | ||
468 | cavium,t-rd-hld = <100>; | ||
469 | cavium,t-wr-hld = <30>; | ||
470 | cavium,t-pause = <0>; | ||
471 | cavium,t-wait = <30>; | ||
472 | cavium,t-page = <320>; | ||
473 | cavium,t-rd-dly = <0>; | ||
474 | |||
475 | cavium,pages = <0>; | ||
476 | cavium,bus-width = <16>; | ||
477 | }; | ||
478 | cavium,cs-config@6 { | ||
479 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
480 | cavium,cs-index = <6>; | ||
481 | cavium,t-adr = <5>; | ||
482 | cavium,t-ce = <300>; | ||
483 | cavium,t-oe = <270>; | ||
484 | cavium,t-we = <150>; | ||
485 | cavium,t-rd-hld = <100>; | ||
486 | cavium,t-wr-hld = <70>; | ||
487 | cavium,t-pause = <0>; | ||
488 | cavium,t-wait = <0>; | ||
489 | cavium,t-page = <320>; | ||
490 | cavium,t-rd-dly = <0>; | ||
491 | |||
492 | cavium,pages = <0>; | ||
493 | cavium,wait-mode; | ||
494 | cavium,bus-width = <16>; | ||
495 | }; | ||
496 | |||
497 | flash0: nor@0,0 { | ||
498 | compatible = "cfi-flash"; | ||
499 | reg = <0 0 0x800000>; | ||
500 | #address-cells = <1>; | ||
501 | #size-cells = <1>; | ||
502 | }; | ||
503 | |||
504 | led0: led-display@4,0 { | 327 | led0: led-display@4,0 { |
505 | compatible = "avago,hdsp-253x"; | 328 | compatible = "avago,hdsp-253x"; |
506 | reg = <4 0x20 0x20>, <4 0 0x20>; | 329 | reg = <4 0x20 0x20>, <4 0 0x20>; |
@@ -515,17 +338,6 @@ | |||
515 | }; | 338 | }; |
516 | }; | 339 | }; |
517 | 340 | ||
518 | dma0: dma-engine@1180000000100 { | ||
519 | compatible = "cavium,octeon-5750-bootbus-dma"; | ||
520 | reg = <0x11800 0x00000100 0x0 0x8>; | ||
521 | interrupts = <0 63>; | ||
522 | }; | ||
523 | dma1: dma-engine@1180000000108 { | ||
524 | compatible = "cavium,octeon-5750-bootbus-dma"; | ||
525 | reg = <0x11800 0x00000108 0x0 0x8>; | ||
526 | interrupts = <0 63>; | ||
527 | }; | ||
528 | |||
529 | uctl: uctl@118006f000000 { | 341 | uctl: uctl@118006f000000 { |
530 | compatible = "cavium,octeon-6335-uctl"; | 342 | compatible = "cavium,octeon-6335-uctl"; |
531 | reg = <0x11800 0x6f000000 0x0 0x100>; | 343 | reg = <0x11800 0x6f000000 0x0 0x100>; |
@@ -552,21 +364,10 @@ | |||
552 | }; | 364 | }; |
553 | 365 | ||
554 | usbn: usbn@1180068000000 { | 366 | usbn: usbn@1180068000000 { |
555 | compatible = "cavium,octeon-5750-usbn"; | ||
556 | reg = <0x11800 0x68000000 0x0 0x1000>; | ||
557 | ranges; /* Direct mapping */ | ||
558 | #address-cells = <2>; | ||
559 | #size-cells = <2>; | ||
560 | /* 12MHz, 24MHz and 48MHz allowed */ | 367 | /* 12MHz, 24MHz and 48MHz allowed */ |
561 | refclk-frequency = <12000000>; | 368 | refclk-frequency = <12000000>; |
562 | /* Either "crystal" or "external" */ | 369 | /* Either "crystal" or "external" */ |
563 | refclk-type = "crystal"; | 370 | refclk-type = "crystal"; |
564 | |||
565 | usbc@16f0010000000 { | ||
566 | compatible = "cavium,octeon-5750-usbc"; | ||
567 | reg = <0x16f00 0x10000000 0x0 0x80000>; | ||
568 | interrupts = <0 56>; | ||
569 | }; | ||
570 | }; | 371 | }; |
571 | }; | 372 | }; |
572 | 373 | ||
diff --git a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dtsi b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dtsi new file mode 100644 index 000000000000..5302148e05a3 --- /dev/null +++ b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dtsi | |||
@@ -0,0 +1,231 @@ | |||
1 | /* OCTEON 3XXX DTS common parts. */ | ||
2 | |||
3 | /dts-v1/; | ||
4 | |||
5 | / { | ||
6 | compatible = "cavium,octeon-3860"; | ||
7 | #address-cells = <2>; | ||
8 | #size-cells = <2>; | ||
9 | interrupt-parent = <&ciu>; | ||
10 | |||
11 | soc@0 { | ||
12 | compatible = "simple-bus"; | ||
13 | #address-cells = <2>; | ||
14 | #size-cells = <2>; | ||
15 | ranges; /* Direct mapping */ | ||
16 | |||
17 | ciu: interrupt-controller@1070000000000 { | ||
18 | compatible = "cavium,octeon-3860-ciu"; | ||
19 | interrupt-controller; | ||
20 | /* Interrupts are specified by two parts: | ||
21 | * 1) Controller register (0 or 1) | ||
22 | * 2) Bit within the register (0..63) | ||
23 | */ | ||
24 | #interrupt-cells = <2>; | ||
25 | reg = <0x10700 0x00000000 0x0 0x7000>; | ||
26 | }; | ||
27 | |||
28 | gpio: gpio-controller@1070000000800 { | ||
29 | #gpio-cells = <2>; | ||
30 | compatible = "cavium,octeon-3860-gpio"; | ||
31 | reg = <0x10700 0x00000800 0x0 0x100>; | ||
32 | gpio-controller; | ||
33 | /* Interrupts are specified by two parts: | ||
34 | * 1) GPIO pin number (0..15) | ||
35 | * 2) Triggering (1 - edge rising | ||
36 | * 2 - edge falling | ||
37 | * 4 - level active high | ||
38 | * 8 - level active low) | ||
39 | */ | ||
40 | interrupt-controller; | ||
41 | #interrupt-cells = <2>; | ||
42 | /* The GPIO pin connect to 16 consecutive CUI bits */ | ||
43 | interrupts = <0 16>, <0 17>, <0 18>, <0 19>, | ||
44 | <0 20>, <0 21>, <0 22>, <0 23>, | ||
45 | <0 24>, <0 25>, <0 26>, <0 27>, | ||
46 | <0 28>, <0 29>, <0 30>, <0 31>; | ||
47 | }; | ||
48 | |||
49 | smi0: mdio@1180000001800 { | ||
50 | compatible = "cavium,octeon-3860-mdio"; | ||
51 | #address-cells = <1>; | ||
52 | #size-cells = <0>; | ||
53 | reg = <0x11800 0x00001800 0x0 0x40>; | ||
54 | }; | ||
55 | |||
56 | pip: pip@11800a0000000 { | ||
57 | compatible = "cavium,octeon-3860-pip"; | ||
58 | #address-cells = <1>; | ||
59 | #size-cells = <0>; | ||
60 | reg = <0x11800 0xa0000000 0x0 0x2000>; | ||
61 | |||
62 | interface@0 { | ||
63 | compatible = "cavium,octeon-3860-pip-interface"; | ||
64 | #address-cells = <1>; | ||
65 | #size-cells = <0>; | ||
66 | reg = <0>; /* interface */ | ||
67 | |||
68 | ethernet@0 { | ||
69 | compatible = "cavium,octeon-3860-pip-port"; | ||
70 | reg = <0x0>; /* Port */ | ||
71 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
72 | }; | ||
73 | ethernet@1 { | ||
74 | compatible = "cavium,octeon-3860-pip-port"; | ||
75 | reg = <0x1>; /* Port */ | ||
76 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
77 | }; | ||
78 | ethernet@2 { | ||
79 | compatible = "cavium,octeon-3860-pip-port"; | ||
80 | reg = <0x2>; /* Port */ | ||
81 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
82 | }; | ||
83 | }; | ||
84 | |||
85 | interface@1 { | ||
86 | compatible = "cavium,octeon-3860-pip-interface"; | ||
87 | #address-cells = <1>; | ||
88 | #size-cells = <0>; | ||
89 | reg = <1>; /* interface */ | ||
90 | }; | ||
91 | }; | ||
92 | |||
93 | twsi0: i2c@1180000001000 { | ||
94 | #address-cells = <1>; | ||
95 | #size-cells = <0>; | ||
96 | compatible = "cavium,octeon-3860-twsi"; | ||
97 | reg = <0x11800 0x00001000 0x0 0x200>; | ||
98 | interrupts = <0 45>; | ||
99 | clock-frequency = <100000>; | ||
100 | }; | ||
101 | |||
102 | uart0: serial@1180000000800 { | ||
103 | compatible = "cavium,octeon-3860-uart","ns16550"; | ||
104 | reg = <0x11800 0x00000800 0x0 0x400>; | ||
105 | clock-frequency = <0>; | ||
106 | current-speed = <115200>; | ||
107 | reg-shift = <3>; | ||
108 | interrupts = <0 34>; | ||
109 | }; | ||
110 | |||
111 | bootbus: bootbus@1180000000000 { | ||
112 | compatible = "cavium,octeon-3860-bootbus"; | ||
113 | reg = <0x11800 0x00000000 0x0 0x200>; | ||
114 | /* The chip select number and offset */ | ||
115 | #address-cells = <2>; | ||
116 | /* The size of the chip select region */ | ||
117 | #size-cells = <1>; | ||
118 | ranges = <0 0 0x0 0x1f400000 0xc00000>, | ||
119 | <1 0 0x10000 0x30000000 0>, | ||
120 | <2 0 0x10000 0x40000000 0>, | ||
121 | <3 0 0x10000 0x50000000 0>, | ||
122 | <4 0 0x0 0x1d020000 0x10000>, | ||
123 | <5 0 0x0 0x1d040000 0x10000>, | ||
124 | <6 0 0x0 0x1d050000 0x10000>, | ||
125 | <7 0 0x10000 0x90000000 0>; | ||
126 | |||
127 | cavium,cs-config@0 { | ||
128 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
129 | cavium,cs-index = <0>; | ||
130 | cavium,t-adr = <20>; | ||
131 | cavium,t-ce = <60>; | ||
132 | cavium,t-oe = <60>; | ||
133 | cavium,t-we = <45>; | ||
134 | cavium,t-rd-hld = <35>; | ||
135 | cavium,t-wr-hld = <45>; | ||
136 | cavium,t-pause = <0>; | ||
137 | cavium,t-wait = <0>; | ||
138 | cavium,t-page = <35>; | ||
139 | cavium,t-rd-dly = <0>; | ||
140 | |||
141 | cavium,pages = <0>; | ||
142 | cavium,bus-width = <8>; | ||
143 | }; | ||
144 | cavium,cs-config@4 { | ||
145 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
146 | cavium,cs-index = <4>; | ||
147 | cavium,t-adr = <320>; | ||
148 | cavium,t-ce = <320>; | ||
149 | cavium,t-oe = <320>; | ||
150 | cavium,t-we = <320>; | ||
151 | cavium,t-rd-hld = <320>; | ||
152 | cavium,t-wr-hld = <320>; | ||
153 | cavium,t-pause = <320>; | ||
154 | cavium,t-wait = <320>; | ||
155 | cavium,t-page = <320>; | ||
156 | cavium,t-rd-dly = <0>; | ||
157 | |||
158 | cavium,pages = <0>; | ||
159 | cavium,bus-width = <8>; | ||
160 | }; | ||
161 | cavium,cs-config@5 { | ||
162 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
163 | cavium,cs-index = <5>; | ||
164 | cavium,t-adr = <5>; | ||
165 | cavium,t-ce = <300>; | ||
166 | cavium,t-oe = <125>; | ||
167 | cavium,t-we = <150>; | ||
168 | cavium,t-rd-hld = <100>; | ||
169 | cavium,t-wr-hld = <30>; | ||
170 | cavium,t-pause = <0>; | ||
171 | cavium,t-wait = <30>; | ||
172 | cavium,t-page = <320>; | ||
173 | cavium,t-rd-dly = <0>; | ||
174 | |||
175 | cavium,pages = <0>; | ||
176 | cavium,bus-width = <16>; | ||
177 | }; | ||
178 | cavium,cs-config@6 { | ||
179 | compatible = "cavium,octeon-3860-bootbus-config"; | ||
180 | cavium,cs-index = <6>; | ||
181 | cavium,t-adr = <5>; | ||
182 | cavium,t-ce = <300>; | ||
183 | cavium,t-oe = <270>; | ||
184 | cavium,t-we = <150>; | ||
185 | cavium,t-rd-hld = <100>; | ||
186 | cavium,t-wr-hld = <70>; | ||
187 | cavium,t-pause = <0>; | ||
188 | cavium,t-wait = <0>; | ||
189 | cavium,t-page = <320>; | ||
190 | cavium,t-rd-dly = <0>; | ||
191 | |||
192 | cavium,pages = <0>; | ||
193 | cavium,wait-mode; | ||
194 | cavium,bus-width = <16>; | ||
195 | }; | ||
196 | |||
197 | flash0: nor@0,0 { | ||
198 | compatible = "cfi-flash"; | ||
199 | reg = <0 0 0x800000>; | ||
200 | #address-cells = <1>; | ||
201 | #size-cells = <1>; | ||
202 | }; | ||
203 | }; | ||
204 | |||
205 | dma0: dma-engine@1180000000100 { | ||
206 | compatible = "cavium,octeon-5750-bootbus-dma"; | ||
207 | reg = <0x11800 0x00000100 0x0 0x8>; | ||
208 | interrupts = <0 63>; | ||
209 | }; | ||
210 | |||
211 | dma1: dma-engine@1180000000108 { | ||
212 | compatible = "cavium,octeon-5750-bootbus-dma"; | ||
213 | reg = <0x11800 0x00000108 0x0 0x8>; | ||
214 | interrupts = <0 63>; | ||
215 | }; | ||
216 | |||
217 | usbn: usbn@1180068000000 { | ||
218 | compatible = "cavium,octeon-5750-usbn"; | ||
219 | reg = <0x11800 0x68000000 0x0 0x1000>; | ||
220 | ranges; /* Direct mapping */ | ||
221 | #address-cells = <2>; | ||
222 | #size-cells = <2>; | ||
223 | |||
224 | usbc@16f0010000000 { | ||
225 | compatible = "cavium,octeon-5750-usbc"; | ||
226 | reg = <0x16f00 0x10000000 0x0 0x80000>; | ||
227 | interrupts = <0 56>; | ||
228 | }; | ||
229 | }; | ||
230 | }; | ||
231 | }; | ||
diff --git a/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts b/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts new file mode 100644 index 000000000000..243e5dc444fb --- /dev/null +++ b/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Device tree source for EdgeRouter Lite. | ||
3 | * | ||
4 | * Written by: Aaro Koskinen <aaro.koskinen@iki.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | /include/ "octeon_3xxx.dtsi" | ||
12 | |||
13 | / { | ||
14 | model = "ubnt,e100"; | ||
15 | |||
16 | soc@0 { | ||
17 | smi0: mdio@1180000001800 { | ||
18 | phy5: ethernet-phy@5 { | ||
19 | reg = <5>; | ||
20 | compatible = "ethernet-phy-ieee802.3-c22"; | ||
21 | }; | ||
22 | phy6: ethernet-phy@6 { | ||
23 | reg = <6>; | ||
24 | compatible = "ethernet-phy-ieee802.3-c22"; | ||
25 | }; | ||
26 | phy7: ethernet-phy@7 { | ||
27 | reg = <7>; | ||
28 | compatible = "ethernet-phy-ieee802.3-c22"; | ||
29 | }; | ||
30 | }; | ||
31 | |||
32 | pip: pip@11800a0000000 { | ||
33 | interface@0 { | ||
34 | ethernet@0 { | ||
35 | phy-handle = <&phy7>; | ||
36 | }; | ||
37 | ethernet@1 { | ||
38 | phy-handle = <&phy6>; | ||
39 | }; | ||
40 | ethernet@2 { | ||
41 | phy-handle = <&phy5>; | ||
42 | }; | ||
43 | }; | ||
44 | }; | ||
45 | |||
46 | uart0: serial@1180000000800 { | ||
47 | clock-frequency = <500000000>; | ||
48 | }; | ||
49 | |||
50 | usbn: usbn@1180068000000 { | ||
51 | refclk-frequency = <12000000>; | ||
52 | refclk-type = "crystal"; | ||
53 | }; | ||
54 | }; | ||
55 | |||
56 | aliases { | ||
57 | pip = &pip; | ||
58 | }; | ||
59 | }; | ||
diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi index 8b2437cd019f..4a9c8f2a72d6 100644 --- a/arch/mips/boot/dts/ingenic/jz4740.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi | |||
@@ -65,4 +65,18 @@ | |||
65 | clocks = <&ext>, <&cgu JZ4740_CLK_UART1>; | 65 | clocks = <&ext>, <&cgu JZ4740_CLK_UART1>; |
66 | clock-names = "baud", "module"; | 66 | clock-names = "baud", "module"; |
67 | }; | 67 | }; |
68 | |||
69 | uhc: uhc@13030000 { | ||
70 | compatible = "ingenic,jz4740-ohci", "generic-ohci"; | ||
71 | reg = <0x13030000 0x1000>; | ||
72 | |||
73 | clocks = <&cgu JZ4740_CLK_UHC>; | ||
74 | assigned-clocks = <&cgu JZ4740_CLK_UHC>; | ||
75 | assigned-clock-rates = <48000000>; | ||
76 | |||
77 | interrupt-parent = <&intc>; | ||
78 | interrupts = <3>; | ||
79 | |||
80 | status = "disabled"; | ||
81 | }; | ||
68 | }; | 82 | }; |
diff --git a/arch/mips/boot/dts/lantiq/easy50712.dts b/arch/mips/boot/dts/lantiq/easy50712.dts index 143b8a37b5e4..b59962585dde 100644 --- a/arch/mips/boot/dts/lantiq/easy50712.dts +++ b/arch/mips/boot/dts/lantiq/easy50712.dts | |||
@@ -52,7 +52,7 @@ | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | gpio: pinmux@E100B10 { | 54 | gpio: pinmux@E100B10 { |
55 | compatible = "lantiq,pinctrl-xway"; | 55 | compatible = "lantiq,danube-pinctrl"; |
56 | pinctrl-names = "default"; | 56 | pinctrl-names = "default"; |
57 | pinctrl-0 = <&state_default>; | 57 | pinctrl-0 = <&state_default>; |
58 | 58 | ||
diff --git a/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi b/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi deleted file mode 100644 index ef1335012f43..000000000000 --- a/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | /* | ||
2 | * Device Tree Source for PIC32MZDA clock data | ||
3 | * | ||
4 | * Purna Chandra Mandal <purna.mandal@microchip.com> | ||
5 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
6 | * | ||
7 | * Licensed under GPLv2 or later. | ||
8 | */ | ||
9 | |||
10 | /* all fixed rate clocks */ | ||
11 | |||
12 | / { | ||
13 | POSC:posc_clk { /* On-chip primary oscillator */ | ||
14 | #clock-cells = <0>; | ||
15 | compatible = "fixed-clock"; | ||
16 | clock-frequency = <24000000>; | ||
17 | }; | ||
18 | |||
19 | FRC:frc_clk { /* internal FRC oscillator */ | ||
20 | #clock-cells = <0>; | ||
21 | compatible = "fixed-clock"; | ||
22 | clock-frequency = <8000000>; | ||
23 | }; | ||
24 | |||
25 | BFRC:bfrc_clk { /* internal backup FRC oscillator */ | ||
26 | #clock-cells = <0>; | ||
27 | compatible = "fixed-clock"; | ||
28 | clock-frequency = <8000000>; | ||
29 | }; | ||
30 | |||
31 | LPRC:lprc_clk { /* internal low-power FRC oscillator */ | ||
32 | #clock-cells = <0>; | ||
33 | compatible = "fixed-clock"; | ||
34 | clock-frequency = <32000>; | ||
35 | }; | ||
36 | |||
37 | /* UPLL provides clock to USBCORE */ | ||
38 | UPLL:usb_phy_clk { | ||
39 | #clock-cells = <0>; | ||
40 | compatible = "fixed-clock"; | ||
41 | clock-frequency = <24000000>; | ||
42 | clock-output-names = "usbphy_clk"; | ||
43 | }; | ||
44 | |||
45 | TxCKI:txcki_clk { /* external clock input on TxCLKI pin */ | ||
46 | #clock-cells = <0>; | ||
47 | compatible = "fixed-clock"; | ||
48 | clock-frequency = <4000000>; | ||
49 | status = "disabled"; | ||
50 | }; | ||
51 | |||
52 | /* external clock input on REFCLKIx pin */ | ||
53 | REFIx:refix_clk { | ||
54 | #clock-cells = <0>; | ||
55 | compatible = "fixed-clock"; | ||
56 | clock-frequency = <24000000>; | ||
57 | status = "disabled"; | ||
58 | }; | ||
59 | |||
60 | /* PIC32 specific clks */ | ||
61 | pic32_clktree { | ||
62 | #address-cells = <1>; | ||
63 | #size-cells = <1>; | ||
64 | reg = <0x1f801200 0x200>; | ||
65 | compatible = "microchip,pic32mzda-clk"; | ||
66 | ranges = <0 0x1f801200 0x200>; | ||
67 | |||
68 | /* secondary oscillator; external input on SOSCI pin */ | ||
69 | SOSC:sosc_clk@0 { | ||
70 | #clock-cells = <0>; | ||
71 | compatible = "microchip,pic32mzda-sosc"; | ||
72 | clock-frequency = <32768>; | ||
73 | reg = <0x000 0x10>, /* enable reg */ | ||
74 | <0x1d0 0x10>; /* status reg */ | ||
75 | microchip,bit-mask = <0x02>; /* enable mask */ | ||
76 | microchip,status-bit-mask = <0x10>; /* status-mask*/ | ||
77 | }; | ||
78 | |||
79 | FRCDIV:frcdiv_clk { | ||
80 | #clock-cells = <0>; | ||
81 | compatible = "microchip,pic32mzda-frcdivclk"; | ||
82 | clocks = <&FRC>; | ||
83 | clock-output-names = "frcdiv_clk"; | ||
84 | }; | ||
85 | |||
86 | /* System PLL clock */ | ||
87 | SYSPLL:spll_clk@020 { | ||
88 | #clock-cells = <0>; | ||
89 | compatible = "microchip,pic32mzda-syspll"; | ||
90 | reg = <0x020 0x10>, /* SPLL register */ | ||
91 | <0x1d0 0x10>; /* CLKSTAT register */ | ||
92 | clocks = <&POSC>, <&FRC>; | ||
93 | clock-output-names = "sys_pll"; | ||
94 | microchip,status-bit-mask = <0x80>; /* SPLLRDY */ | ||
95 | }; | ||
96 | |||
97 | /* system clock; mux with postdiv & slew */ | ||
98 | SYSCLK:sys_clk@1c0 { | ||
99 | #clock-cells = <0>; | ||
100 | compatible = "microchip,pic32mzda-sysclk-v2"; | ||
101 | reg = <0x1c0 0x04>; /* SLEWCON */ | ||
102 | clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>, | ||
103 | <&LPRC>, <&FRCDIV>; | ||
104 | microchip,clock-indices = <0>, <1>, <2>, <4>, | ||
105 | <5>, <7>; | ||
106 | clock-output-names = "sys_clk"; | ||
107 | }; | ||
108 | |||
109 | /* Peripheral bus1 clock */ | ||
110 | PBCLK1:pb1_clk@140 { | ||
111 | reg = <0x140 0x10>; | ||
112 | #clock-cells = <0>; | ||
113 | compatible = "microchip,pic32mzda-pbclk"; | ||
114 | clocks = <&SYSCLK>; | ||
115 | clock-output-names = "pb1_clk"; | ||
116 | /* used by system modules, not gateable */ | ||
117 | microchip,ignore-unused; | ||
118 | }; | ||
119 | |||
120 | /* Peripheral bus2 clock */ | ||
121 | PBCLK2:pb2_clk@150 { | ||
122 | reg = <0x150 0x10>; | ||
123 | #clock-cells = <0>; | ||
124 | compatible = "microchip,pic32mzda-pbclk"; | ||
125 | clocks = <&SYSCLK>; | ||
126 | clock-output-names = "pb2_clk"; | ||
127 | /* avoid gating even if unused */ | ||
128 | microchip,ignore-unused; | ||
129 | }; | ||
130 | |||
131 | /* Peripheral bus3 clock */ | ||
132 | PBCLK3:pb3_clk@160 { | ||
133 | reg = <0x160 0x10>; | ||
134 | #clock-cells = <0>; | ||
135 | compatible = "microchip,pic32mzda-pbclk"; | ||
136 | clocks = <&SYSCLK>; | ||
137 | clock-output-names = "pb3_clk"; | ||
138 | }; | ||
139 | |||
140 | /* Peripheral bus4 clock(I/O ports, GPIO) */ | ||
141 | PBCLK4:pb4_clk@170 { | ||
142 | reg = <0x170 0x10>; | ||
143 | #clock-cells = <0>; | ||
144 | compatible = "microchip,pic32mzda-pbclk"; | ||
145 | clocks = <&SYSCLK>; | ||
146 | clock-output-names = "pb4_clk"; | ||
147 | }; | ||
148 | |||
149 | /* Peripheral bus clock */ | ||
150 | PBCLK5:pb5_clk@180 { | ||
151 | reg = <0x180 0x10>; | ||
152 | #clock-cells = <0>; | ||
153 | compatible = "microchip,pic32mzda-pbclk"; | ||
154 | clocks = <&SYSCLK>; | ||
155 | clock-output-names = "pb5_clk"; | ||
156 | }; | ||
157 | |||
158 | /* Peripheral Bus6 clock; */ | ||
159 | PBCLK6:pb6_clk@190 { | ||
160 | reg = <0x190 0x10>; | ||
161 | compatible = "microchip,pic32mzda-pbclk"; | ||
162 | clocks = <&SYSCLK>; | ||
163 | #clock-cells = <0>; | ||
164 | }; | ||
165 | |||
166 | /* Peripheral bus7 clock */ | ||
167 | PBCLK7:pb7_clk@1a0 { | ||
168 | reg = <0x1a0 0x10>; | ||
169 | #clock-cells = <0>; | ||
170 | compatible = "microchip,pic32mzda-pbclk"; | ||
171 | /* CPU is driven by this clock; so named */ | ||
172 | clock-output-names = "cpu_clk"; | ||
173 | clocks = <&SYSCLK>; | ||
174 | }; | ||
175 | |||
176 | /* Reference Oscillator clock for SPI/I2S */ | ||
177 | REFCLKO1:refo1_clk@80 { | ||
178 | reg = <0x080 0x20>; | ||
179 | #clock-cells = <0>; | ||
180 | compatible = "microchip,pic32mzda-refoclk"; | ||
181 | clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>, | ||
182 | <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>; | ||
183 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
184 | <5>, <7>, <8>, <9>; | ||
185 | clock-output-names = "refo1_clk"; | ||
186 | }; | ||
187 | |||
188 | /* Reference Oscillator clock for SQI */ | ||
189 | REFCLKO2:refo2_clk@a0 { | ||
190 | reg = <0x0a0 0x20>; | ||
191 | #clock-cells = <0>; | ||
192 | compatible = "microchip,pic32mzda-refoclk"; | ||
193 | clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>, | ||
194 | <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>; | ||
195 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
196 | <5>, <7>, <8>, <9>; | ||
197 | clock-output-names = "refo2_clk"; | ||
198 | }; | ||
199 | |||
200 | /* Reference Oscillator clock, ADC */ | ||
201 | REFCLKO3:refo3_clk@c0 { | ||
202 | reg = <0x0c0 0x20>; | ||
203 | compatible = "microchip,pic32mzda-refoclk"; | ||
204 | clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>, | ||
205 | <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>; | ||
206 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
207 | <5>, <7>, <8>, <9>; | ||
208 | #clock-cells = <0>; | ||
209 | clock-output-names = "refo3_clk"; | ||
210 | }; | ||
211 | |||
212 | /* Reference Oscillator clock */ | ||
213 | REFCLKO4:refo4_clk@e0 { | ||
214 | reg = <0x0e0 0x20>; | ||
215 | compatible = "microchip,pic32mzda-refoclk"; | ||
216 | clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>, | ||
217 | <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>; | ||
218 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
219 | <5>, <7>, <8>, <9>; | ||
220 | #clock-cells = <0>; | ||
221 | clock-output-names = "refo4_clk"; | ||
222 | }; | ||
223 | |||
224 | /* Reference Oscillator clock, LCD */ | ||
225 | REFCLKO5:refo5_clk@100 { | ||
226 | reg = <0x100 0x20>; | ||
227 | compatible = "microchip,pic32mzda-refoclk"; | ||
228 | clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>, | ||
229 | <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>; | ||
230 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
231 | <5>, <7>, <8>, <9>; | ||
232 | #clock-cells = <0>; | ||
233 | clock-output-names = "refo5_clk"; | ||
234 | }; | ||
235 | }; | ||
236 | }; | ||
diff --git a/arch/mips/boot/dts/pic32/pic32mzda.dtsi b/arch/mips/boot/dts/pic32/pic32mzda.dtsi index ad9e3318c2ce..5353a639c4fb 100644 --- a/arch/mips/boot/dts/pic32/pic32mzda.dtsi +++ b/arch/mips/boot/dts/pic32/pic32mzda.dtsi | |||
@@ -6,11 +6,9 @@ | |||
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | #include <dt-bindings/clock/microchip,pic32-clock.h> | |
10 | #include <dt-bindings/interrupt-controller/irq.h> | 10 | #include <dt-bindings/interrupt-controller/irq.h> |
11 | 11 | ||
12 | #include "pic32mzda-clk.dtsi" | ||
13 | |||
14 | / { | 12 | / { |
15 | #address-cells = <1>; | 13 | #address-cells = <1>; |
16 | #size-cells = <1>; | 14 | #size-cells = <1>; |
@@ -50,6 +48,29 @@ | |||
50 | interrupts = <0 IRQ_TYPE_EDGE_RISING>; | 48 | interrupts = <0 IRQ_TYPE_EDGE_RISING>; |
51 | }; | 49 | }; |
52 | 50 | ||
51 | /* external clock input on TxCLKI pin */ | ||
52 | txcki: txcki_clk { | ||
53 | #clock-cells = <0>; | ||
54 | compatible = "fixed-clock"; | ||
55 | clock-frequency = <4000000>; | ||
56 | status = "disabled"; | ||
57 | }; | ||
58 | |||
59 | /* external input on REFCLKIx pin */ | ||
60 | refix: refix_clk { | ||
61 | #clock-cells = <0>; | ||
62 | compatible = "fixed-clock"; | ||
63 | clock-frequency = <24000000>; | ||
64 | status = "disabled"; | ||
65 | }; | ||
66 | |||
67 | rootclk: clock-controller@1f801200 { | ||
68 | compatible = "microchip,pic32mzda-clk"; | ||
69 | reg = <0x1f801200 0x200>; | ||
70 | #clock-cells = <1>; | ||
71 | microchip,pic32mzda-sosc; | ||
72 | }; | ||
73 | |||
53 | evic: interrupt-controller@1f810000 { | 74 | evic: interrupt-controller@1f810000 { |
54 | compatible = "microchip,pic32mzda-evic"; | 75 | compatible = "microchip,pic32mzda-evic"; |
55 | interrupt-controller; | 76 | interrupt-controller; |
@@ -63,7 +84,7 @@ | |||
63 | #size-cells = <1>; | 84 | #size-cells = <1>; |
64 | compatible = "microchip,pic32mzda-pinctrl"; | 85 | compatible = "microchip,pic32mzda-pinctrl"; |
65 | reg = <0x1f801400 0x400>; | 86 | reg = <0x1f801400 0x400>; |
66 | clocks = <&PBCLK1>; | 87 | clocks = <&rootclk PB1CLK>; |
67 | }; | 88 | }; |
68 | 89 | ||
69 | /* PORTA */ | 90 | /* PORTA */ |
@@ -75,7 +96,7 @@ | |||
75 | gpio-controller; | 96 | gpio-controller; |
76 | interrupt-controller; | 97 | interrupt-controller; |
77 | #interrupt-cells = <2>; | 98 | #interrupt-cells = <2>; |
78 | clocks = <&PBCLK4>; | 99 | clocks = <&rootclk PB4CLK>; |
79 | microchip,gpio-bank = <0>; | 100 | microchip,gpio-bank = <0>; |
80 | gpio-ranges = <&pic32_pinctrl 0 0 16>; | 101 | gpio-ranges = <&pic32_pinctrl 0 0 16>; |
81 | }; | 102 | }; |
@@ -89,7 +110,7 @@ | |||
89 | gpio-controller; | 110 | gpio-controller; |
90 | interrupt-controller; | 111 | interrupt-controller; |
91 | #interrupt-cells = <2>; | 112 | #interrupt-cells = <2>; |
92 | clocks = <&PBCLK4>; | 113 | clocks = <&rootclk PB4CLK>; |
93 | microchip,gpio-bank = <1>; | 114 | microchip,gpio-bank = <1>; |
94 | gpio-ranges = <&pic32_pinctrl 0 16 16>; | 115 | gpio-ranges = <&pic32_pinctrl 0 16 16>; |
95 | }; | 116 | }; |
@@ -103,7 +124,7 @@ | |||
103 | gpio-controller; | 124 | gpio-controller; |
104 | interrupt-controller; | 125 | interrupt-controller; |
105 | #interrupt-cells = <2>; | 126 | #interrupt-cells = <2>; |
106 | clocks = <&PBCLK4>; | 127 | clocks = <&rootclk PB4CLK>; |
107 | microchip,gpio-bank = <2>; | 128 | microchip,gpio-bank = <2>; |
108 | gpio-ranges = <&pic32_pinctrl 0 32 16>; | 129 | gpio-ranges = <&pic32_pinctrl 0 32 16>; |
109 | }; | 130 | }; |
@@ -117,7 +138,7 @@ | |||
117 | gpio-controller; | 138 | gpio-controller; |
118 | interrupt-controller; | 139 | interrupt-controller; |
119 | #interrupt-cells = <2>; | 140 | #interrupt-cells = <2>; |
120 | clocks = <&PBCLK4>; | 141 | clocks = <&rootclk PB4CLK>; |
121 | microchip,gpio-bank = <3>; | 142 | microchip,gpio-bank = <3>; |
122 | gpio-ranges = <&pic32_pinctrl 0 48 16>; | 143 | gpio-ranges = <&pic32_pinctrl 0 48 16>; |
123 | }; | 144 | }; |
@@ -131,7 +152,7 @@ | |||
131 | gpio-controller; | 152 | gpio-controller; |
132 | interrupt-controller; | 153 | interrupt-controller; |
133 | #interrupt-cells = <2>; | 154 | #interrupt-cells = <2>; |
134 | clocks = <&PBCLK4>; | 155 | clocks = <&rootclk PB4CLK>; |
135 | microchip,gpio-bank = <4>; | 156 | microchip,gpio-bank = <4>; |
136 | gpio-ranges = <&pic32_pinctrl 0 64 16>; | 157 | gpio-ranges = <&pic32_pinctrl 0 64 16>; |
137 | }; | 158 | }; |
@@ -145,7 +166,7 @@ | |||
145 | gpio-controller; | 166 | gpio-controller; |
146 | interrupt-controller; | 167 | interrupt-controller; |
147 | #interrupt-cells = <2>; | 168 | #interrupt-cells = <2>; |
148 | clocks = <&PBCLK4>; | 169 | clocks = <&rootclk PB4CLK>; |
149 | microchip,gpio-bank = <5>; | 170 | microchip,gpio-bank = <5>; |
150 | gpio-ranges = <&pic32_pinctrl 0 80 16>; | 171 | gpio-ranges = <&pic32_pinctrl 0 80 16>; |
151 | }; | 172 | }; |
@@ -159,7 +180,7 @@ | |||
159 | gpio-controller; | 180 | gpio-controller; |
160 | interrupt-controller; | 181 | interrupt-controller; |
161 | #interrupt-cells = <2>; | 182 | #interrupt-cells = <2>; |
162 | clocks = <&PBCLK4>; | 183 | clocks = <&rootclk PB4CLK>; |
163 | microchip,gpio-bank = <6>; | 184 | microchip,gpio-bank = <6>; |
164 | gpio-ranges = <&pic32_pinctrl 0 96 16>; | 185 | gpio-ranges = <&pic32_pinctrl 0 96 16>; |
165 | }; | 186 | }; |
@@ -173,7 +194,7 @@ | |||
173 | gpio-controller; | 194 | gpio-controller; |
174 | interrupt-controller; | 195 | interrupt-controller; |
175 | #interrupt-cells = <2>; | 196 | #interrupt-cells = <2>; |
176 | clocks = <&PBCLK4>; | 197 | clocks = <&rootclk PB4CLK>; |
177 | microchip,gpio-bank = <7>; | 198 | microchip,gpio-bank = <7>; |
178 | gpio-ranges = <&pic32_pinctrl 0 112 16>; | 199 | gpio-ranges = <&pic32_pinctrl 0 112 16>; |
179 | }; | 200 | }; |
@@ -189,7 +210,7 @@ | |||
189 | gpio-controller; | 210 | gpio-controller; |
190 | interrupt-controller; | 211 | interrupt-controller; |
191 | #interrupt-cells = <2>; | 212 | #interrupt-cells = <2>; |
192 | clocks = <&PBCLK4>; | 213 | clocks = <&rootclk PB4CLK>; |
193 | microchip,gpio-bank = <8>; | 214 | microchip,gpio-bank = <8>; |
194 | gpio-ranges = <&pic32_pinctrl 0 128 16>; | 215 | gpio-ranges = <&pic32_pinctrl 0 128 16>; |
195 | }; | 216 | }; |
@@ -203,7 +224,7 @@ | |||
203 | gpio-controller; | 224 | gpio-controller; |
204 | interrupt-controller; | 225 | interrupt-controller; |
205 | #interrupt-cells = <2>; | 226 | #interrupt-cells = <2>; |
206 | clocks = <&PBCLK4>; | 227 | clocks = <&rootclk PB4CLK>; |
207 | microchip,gpio-bank = <9>; | 228 | microchip,gpio-bank = <9>; |
208 | gpio-ranges = <&pic32_pinctrl 0 144 16>; | 229 | gpio-ranges = <&pic32_pinctrl 0 144 16>; |
209 | }; | 230 | }; |
@@ -212,7 +233,7 @@ | |||
212 | compatible = "microchip,pic32mzda-sdhci"; | 233 | compatible = "microchip,pic32mzda-sdhci"; |
213 | reg = <0x1f8ec000 0x100>; | 234 | reg = <0x1f8ec000 0x100>; |
214 | interrupts = <191 IRQ_TYPE_LEVEL_HIGH>; | 235 | interrupts = <191 IRQ_TYPE_LEVEL_HIGH>; |
215 | clocks = <&REFCLKO4>, <&PBCLK5>; | 236 | clocks = <&rootclk REF4CLK>, <&rootclk PB5CLK>; |
216 | clock-names = "base_clk", "sys_clk"; | 237 | clock-names = "base_clk", "sys_clk"; |
217 | bus-width = <4>; | 238 | bus-width = <4>; |
218 | cap-sd-highspeed; | 239 | cap-sd-highspeed; |
@@ -225,7 +246,7 @@ | |||
225 | interrupts = <112 IRQ_TYPE_LEVEL_HIGH>, | 246 | interrupts = <112 IRQ_TYPE_LEVEL_HIGH>, |
226 | <113 IRQ_TYPE_LEVEL_HIGH>, | 247 | <113 IRQ_TYPE_LEVEL_HIGH>, |
227 | <114 IRQ_TYPE_LEVEL_HIGH>; | 248 | <114 IRQ_TYPE_LEVEL_HIGH>; |
228 | clocks = <&PBCLK2>; | 249 | clocks = <&rootclk PB2CLK>; |
229 | status = "disabled"; | 250 | status = "disabled"; |
230 | }; | 251 | }; |
231 | 252 | ||
@@ -235,7 +256,7 @@ | |||
235 | interrupts = <145 IRQ_TYPE_LEVEL_HIGH>, | 256 | interrupts = <145 IRQ_TYPE_LEVEL_HIGH>, |
236 | <146 IRQ_TYPE_LEVEL_HIGH>, | 257 | <146 IRQ_TYPE_LEVEL_HIGH>, |
237 | <147 IRQ_TYPE_LEVEL_HIGH>; | 258 | <147 IRQ_TYPE_LEVEL_HIGH>; |
238 | clocks = <&PBCLK2>; | 259 | clocks = <&rootclk PB2CLK>; |
239 | status = "disabled"; | 260 | status = "disabled"; |
240 | }; | 261 | }; |
241 | 262 | ||
@@ -245,7 +266,7 @@ | |||
245 | interrupts = <157 IRQ_TYPE_LEVEL_HIGH>, | 266 | interrupts = <157 IRQ_TYPE_LEVEL_HIGH>, |
246 | <158 IRQ_TYPE_LEVEL_HIGH>, | 267 | <158 IRQ_TYPE_LEVEL_HIGH>, |
247 | <159 IRQ_TYPE_LEVEL_HIGH>; | 268 | <159 IRQ_TYPE_LEVEL_HIGH>; |
248 | clocks = <&PBCLK2>; | 269 | clocks = <&rootclk PB2CLK>; |
249 | status = "disabled"; | 270 | status = "disabled"; |
250 | }; | 271 | }; |
251 | 272 | ||
@@ -255,7 +276,7 @@ | |||
255 | interrupts = <170 IRQ_TYPE_LEVEL_HIGH>, | 276 | interrupts = <170 IRQ_TYPE_LEVEL_HIGH>, |
256 | <171 IRQ_TYPE_LEVEL_HIGH>, | 277 | <171 IRQ_TYPE_LEVEL_HIGH>, |
257 | <172 IRQ_TYPE_LEVEL_HIGH>; | 278 | <172 IRQ_TYPE_LEVEL_HIGH>; |
258 | clocks = <&PBCLK2>; | 279 | clocks = <&rootclk PB2CLK>; |
259 | status = "disabled"; | 280 | status = "disabled"; |
260 | }; | 281 | }; |
261 | 282 | ||
@@ -265,7 +286,7 @@ | |||
265 | interrupts = <179 IRQ_TYPE_LEVEL_HIGH>, | 286 | interrupts = <179 IRQ_TYPE_LEVEL_HIGH>, |
266 | <180 IRQ_TYPE_LEVEL_HIGH>, | 287 | <180 IRQ_TYPE_LEVEL_HIGH>, |
267 | <181 IRQ_TYPE_LEVEL_HIGH>; | 288 | <181 IRQ_TYPE_LEVEL_HIGH>; |
268 | clocks = <&PBCLK2>; | 289 | clocks = <&rootclk PB2CLK>; |
269 | status = "disabled"; | 290 | status = "disabled"; |
270 | }; | 291 | }; |
271 | 292 | ||
@@ -275,7 +296,7 @@ | |||
275 | interrupts = <188 IRQ_TYPE_LEVEL_HIGH>, | 296 | interrupts = <188 IRQ_TYPE_LEVEL_HIGH>, |
276 | <189 IRQ_TYPE_LEVEL_HIGH>, | 297 | <189 IRQ_TYPE_LEVEL_HIGH>, |
277 | <190 IRQ_TYPE_LEVEL_HIGH>; | 298 | <190 IRQ_TYPE_LEVEL_HIGH>; |
278 | clocks = <&PBCLK2>; | 299 | clocks = <&rootclk PB2CLK>; |
279 | status = "disabled"; | 300 | status = "disabled"; |
280 | }; | 301 | }; |
281 | }; | 302 | }; |
diff --git a/arch/mips/boot/dts/pic32/pic32mzda_sk.dts b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts index 5d434a50e85b..fc740102852e 100644 --- a/arch/mips/boot/dts/pic32/pic32mzda_sk.dts +++ b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts | |||
@@ -95,8 +95,9 @@ | |||
95 | pinctrl-names = "default"; | 95 | pinctrl-names = "default"; |
96 | pinctrl-0 = <&pinctrl_sdhc1>; | 96 | pinctrl-0 = <&pinctrl_sdhc1>; |
97 | status = "okay"; | 97 | status = "okay"; |
98 | assigned-clocks = <&REFCLKO2>,<&REFCLKO4>,<&REFCLKO5>; | 98 | assigned-clocks = <&rootclk REF2CLK>, <&rootclk REF4CLK>, |
99 | assigned-clock-rates = <50000000>,<25000000>,<40000000>; | 99 | <&rootclk REF5CLK>; |
100 | assigned-clock-rates = <50000000>, <25000000>, <40000000>; | ||
100 | }; | 101 | }; |
101 | 102 | ||
102 | &pic32_pinctrl { | 103 | &pic32_pinctrl { |
diff --git a/arch/mips/boot/dts/qca/Makefile b/arch/mips/boot/dts/qca/Makefile index 2d61455d585d..63a9ddf048c9 100644 --- a/arch/mips/boot/dts/qca/Makefile +++ b/arch/mips/boot/dts/qca/Makefile | |||
@@ -1,8 +1,9 @@ | |||
1 | # All DTBs | 1 | # All DTBs |
2 | dtb-$(CONFIG_ATH79) += ar9132_tl_wr1043nd_v1.dtb | 2 | dtb-$(CONFIG_ATH79) += ar9132_tl_wr1043nd_v1.dtb |
3 | 3 | dtb-$(CONFIG_ATH79) += ar9331_dpt_module.dtb | |
4 | # Select a DTB to build in the kernel | 4 | dtb-$(CONFIG_ATH79) += ar9331_dragino_ms14.dtb |
5 | obj-$(CONFIG_DTB_TL_WR1043ND_V1) += ar9132_tl_wr1043nd_v1.dtb.o | 5 | dtb-$(CONFIG_ATH79) += ar9331_omega.dtb |
6 | dtb-$(CONFIG_ATH79) += ar9331_tl_mr3020.dtb | ||
6 | 7 | ||
7 | # Force kbuild to make empty built-in.o if necessary | 8 | # Force kbuild to make empty built-in.o if necessary |
8 | obj- += dummy.o | 9 | obj- += dummy.o |
diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi index 3c2ed9ee5b2f..302f0a8d2988 100644 --- a/arch/mips/boot/dts/qca/ar9132.dtsi +++ b/arch/mips/boot/dts/qca/ar9132.dtsi | |||
@@ -1,3 +1,5 @@ | |||
1 | #include <dt-bindings/clock/ath79-clk.h> | ||
2 | |||
1 | / { | 3 | / { |
2 | compatible = "qca,ar9132"; | 4 | compatible = "qca,ar9132"; |
3 | 5 | ||
@@ -11,6 +13,7 @@ | |||
11 | cpu@0 { | 13 | cpu@0 { |
12 | device_type = "cpu"; | 14 | device_type = "cpu"; |
13 | compatible = "mips,mips24Kc"; | 15 | compatible = "mips,mips24Kc"; |
16 | clocks = <&pll ATH79_CLK_CPU>; | ||
14 | reg = <0>; | 17 | reg = <0>; |
15 | }; | 18 | }; |
16 | }; | 19 | }; |
@@ -52,12 +55,12 @@ | |||
52 | #qca,ddr-wb-channel-cells = <1>; | 55 | #qca,ddr-wb-channel-cells = <1>; |
53 | }; | 56 | }; |
54 | 57 | ||
55 | uart@18020000 { | 58 | uart: uart@18020000 { |
56 | compatible = "ns8250"; | 59 | compatible = "ns8250"; |
57 | reg = <0x18020000 0x20>; | 60 | reg = <0x18020000 0x20>; |
58 | interrupts = <3>; | 61 | interrupts = <3>; |
59 | 62 | ||
60 | clocks = <&pll 2>; | 63 | clocks = <&pll ATH79_CLK_AHB>; |
61 | clock-names = "uart"; | 64 | clock-names = "uart"; |
62 | 65 | ||
63 | reg-io-width = <4>; | 66 | reg-io-width = <4>; |
@@ -94,13 +97,13 @@ | |||
94 | clock-output-names = "cpu", "ddr", "ahb"; | 97 | clock-output-names = "cpu", "ddr", "ahb"; |
95 | }; | 98 | }; |
96 | 99 | ||
97 | wdt@18060008 { | 100 | wdt: wdt@18060008 { |
98 | compatible = "qca,ar7130-wdt"; | 101 | compatible = "qca,ar7130-wdt"; |
99 | reg = <0x18060008 0x8>; | 102 | reg = <0x18060008 0x8>; |
100 | 103 | ||
101 | interrupts = <4>; | 104 | interrupts = <4>; |
102 | 105 | ||
103 | clocks = <&pll 2>; | 106 | clocks = <&pll ATH79_CLK_AHB>; |
104 | clock-names = "wdt"; | 107 | clock-names = "wdt"; |
105 | }; | 108 | }; |
106 | 109 | ||
@@ -125,7 +128,7 @@ | |||
125 | }; | 128 | }; |
126 | }; | 129 | }; |
127 | 130 | ||
128 | usb@1b000100 { | 131 | usb: usb@1b000100 { |
129 | compatible = "qca,ar7100-ehci", "generic-ehci"; | 132 | compatible = "qca,ar7100-ehci", "generic-ehci"; |
130 | reg = <0x1b000100 0x100>; | 133 | reg = <0x1b000100 0x100>; |
131 | 134 | ||
@@ -140,11 +143,11 @@ | |||
140 | status = "disabled"; | 143 | status = "disabled"; |
141 | }; | 144 | }; |
142 | 145 | ||
143 | spi@1f000000 { | 146 | spi: spi@1f000000 { |
144 | compatible = "qca,ar9132-spi", "qca,ar7100-spi"; | 147 | compatible = "qca,ar9132-spi", "qca,ar7100-spi"; |
145 | reg = <0x1f000000 0x10>; | 148 | reg = <0x1f000000 0x10>; |
146 | 149 | ||
147 | clocks = <&pll 2>; | 150 | clocks = <&pll ATH79_CLK_AHB>; |
148 | clock-names = "ahb"; | 151 | clock-names = "ahb"; |
149 | 152 | ||
150 | status = "disabled"; | 153 | status = "disabled"; |
diff --git a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts index 4f1540e5f963..3c3b7ce5737b 100644 --- a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts +++ b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts | |||
@@ -9,10 +9,6 @@ | |||
9 | compatible = "tplink,tl-wr1043nd-v1", "qca,ar9132"; | 9 | compatible = "tplink,tl-wr1043nd-v1", "qca,ar9132"; |
10 | model = "TP-Link TL-WR1043ND Version 1"; | 10 | model = "TP-Link TL-WR1043ND Version 1"; |
11 | 11 | ||
12 | alias { | ||
13 | serial0 = "/ahb/apb/uart@18020000"; | ||
14 | }; | ||
15 | |||
16 | memory@0 { | 12 | memory@0 { |
17 | device_type = "memory"; | 13 | device_type = "memory"; |
18 | reg = <0x0 0x2000000>; | 14 | reg = <0x0 0x2000000>; |
@@ -24,55 +20,6 @@ | |||
24 | clock-frequency = <40000000>; | 20 | clock-frequency = <40000000>; |
25 | }; | 21 | }; |
26 | 22 | ||
27 | ahb { | ||
28 | apb { | ||
29 | uart@18020000 { | ||
30 | status = "okay"; | ||
31 | }; | ||
32 | |||
33 | pll-controller@18050000 { | ||
34 | clocks = <&extosc>; | ||
35 | }; | ||
36 | }; | ||
37 | |||
38 | usb@1b000100 { | ||
39 | status = "okay"; | ||
40 | }; | ||
41 | |||
42 | spi@1f000000 { | ||
43 | status = "okay"; | ||
44 | num-cs = <1>; | ||
45 | |||
46 | flash@0 { | ||
47 | #address-cells = <1>; | ||
48 | #size-cells = <1>; | ||
49 | compatible = "s25sl064a"; | ||
50 | reg = <0>; | ||
51 | spi-max-frequency = <25000000>; | ||
52 | |||
53 | partition@0 { | ||
54 | label = "u-boot"; | ||
55 | reg = <0x000000 0x020000>; | ||
56 | }; | ||
57 | |||
58 | partition@1 { | ||
59 | label = "firmware"; | ||
60 | reg = <0x020000 0x7D0000>; | ||
61 | }; | ||
62 | |||
63 | partition@2 { | ||
64 | label = "art"; | ||
65 | reg = <0x7F0000 0x010000>; | ||
66 | read-only; | ||
67 | }; | ||
68 | }; | ||
69 | }; | ||
70 | }; | ||
71 | |||
72 | usb-phy { | ||
73 | status = "okay"; | ||
74 | }; | ||
75 | |||
76 | gpio-keys { | 23 | gpio-keys { |
77 | compatible = "gpio-keys-polled"; | 24 | compatible = "gpio-keys-polled"; |
78 | #address-cells = <1>; | 25 | #address-cells = <1>; |
@@ -118,3 +65,48 @@ | |||
118 | }; | 65 | }; |
119 | }; | 66 | }; |
120 | }; | 67 | }; |
68 | |||
69 | &uart { | ||
70 | status = "okay"; | ||
71 | }; | ||
72 | |||
73 | &pll { | ||
74 | clocks = <&extosc>; | ||
75 | }; | ||
76 | |||
77 | &usb { | ||
78 | status = "okay"; | ||
79 | }; | ||
80 | |||
81 | &usb_phy { | ||
82 | status = "okay"; | ||
83 | }; | ||
84 | |||
85 | &spi { | ||
86 | status = "okay"; | ||
87 | num-cs = <1>; | ||
88 | |||
89 | flash@0 { | ||
90 | #address-cells = <1>; | ||
91 | #size-cells = <1>; | ||
92 | compatible = "s25sl064a"; | ||
93 | reg = <0>; | ||
94 | spi-max-frequency = <25000000>; | ||
95 | |||
96 | partition@0 { | ||
97 | label = "u-boot"; | ||
98 | reg = <0x000000 0x020000>; | ||
99 | }; | ||
100 | |||
101 | partition@1 { | ||
102 | label = "firmware"; | ||
103 | reg = <0x020000 0x7D0000>; | ||
104 | }; | ||
105 | |||
106 | partition@2 { | ||
107 | label = "art"; | ||
108 | reg = <0x7F0000 0x010000>; | ||
109 | read-only; | ||
110 | }; | ||
111 | }; | ||
112 | }; | ||
diff --git a/arch/mips/boot/dts/qca/ar9331.dtsi b/arch/mips/boot/dts/qca/ar9331.dtsi new file mode 100644 index 000000000000..cf47ed4d8569 --- /dev/null +++ b/arch/mips/boot/dts/qca/ar9331.dtsi | |||
@@ -0,0 +1,155 @@ | |||
1 | #include <dt-bindings/clock/ath79-clk.h> | ||
2 | |||
3 | / { | ||
4 | compatible = "qca,ar9331"; | ||
5 | |||
6 | #address-cells = <1>; | ||
7 | #size-cells = <1>; | ||
8 | |||
9 | cpus { | ||
10 | #address-cells = <1>; | ||
11 | #size-cells = <0>; | ||
12 | |||
13 | cpu@0 { | ||
14 | device_type = "cpu"; | ||
15 | compatible = "mips,mips24Kc"; | ||
16 | clocks = <&pll ATH79_CLK_CPU>; | ||
17 | reg = <0>; | ||
18 | }; | ||
19 | }; | ||
20 | |||
21 | cpuintc: interrupt-controller { | ||
22 | compatible = "qca,ar7100-cpu-intc"; | ||
23 | |||
24 | interrupt-controller; | ||
25 | #interrupt-cells = <1>; | ||
26 | |||
27 | qca,ddr-wb-channel-interrupts = <2>, <3>; | ||
28 | qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>; | ||
29 | }; | ||
30 | |||
31 | ref: ref { | ||
32 | compatible = "fixed-clock"; | ||
33 | #clock-cells = <0>; | ||
34 | }; | ||
35 | |||
36 | ahb { | ||
37 | compatible = "simple-bus"; | ||
38 | ranges; | ||
39 | |||
40 | #address-cells = <1>; | ||
41 | #size-cells = <1>; | ||
42 | |||
43 | interrupt-parent = <&cpuintc>; | ||
44 | |||
45 | apb { | ||
46 | compatible = "simple-bus"; | ||
47 | ranges; | ||
48 | |||
49 | #address-cells = <1>; | ||
50 | #size-cells = <1>; | ||
51 | |||
52 | interrupt-parent = <&miscintc>; | ||
53 | |||
54 | ddr_ctrl: memory-controller@18000000 { | ||
55 | compatible = "qca,ar7240-ddr-controller"; | ||
56 | reg = <0x18000000 0x100>; | ||
57 | |||
58 | #qca,ddr-wb-channel-cells = <1>; | ||
59 | }; | ||
60 | |||
61 | uart: uart@18020000 { | ||
62 | compatible = "qca,ar9330-uart"; | ||
63 | reg = <0x18020000 0x14>; | ||
64 | |||
65 | interrupts = <3>; | ||
66 | |||
67 | clocks = <&ref>; | ||
68 | clock-names = "uart"; | ||
69 | |||
70 | status = "disabled"; | ||
71 | }; | ||
72 | |||
73 | gpio: gpio@18040000 { | ||
74 | compatible = "qca,ar7100-gpio"; | ||
75 | reg = <0x18040000 0x34>; | ||
76 | interrupts = <2>; | ||
77 | |||
78 | ngpios = <30>; | ||
79 | |||
80 | gpio-controller; | ||
81 | #gpio-cells = <2>; | ||
82 | |||
83 | interrupt-controller; | ||
84 | #interrupt-cells = <2>; | ||
85 | |||
86 | status = "disabled"; | ||
87 | }; | ||
88 | |||
89 | pll: pll-controller@18050000 { | ||
90 | compatible = "qca,ar9330-pll"; | ||
91 | reg = <0x18050000 0x100>; | ||
92 | |||
93 | clocks = <&ref>; | ||
94 | clock-names = "ref"; | ||
95 | |||
96 | #clock-cells = <1>; | ||
97 | }; | ||
98 | |||
99 | miscintc: interrupt-controller@18060010 { | ||
100 | compatible = "qca,ar7240-misc-intc"; | ||
101 | reg = <0x18060010 0x4>; | ||
102 | |||
103 | interrupt-parent = <&cpuintc>; | ||
104 | interrupts = <6>; | ||
105 | |||
106 | interrupt-controller; | ||
107 | #interrupt-cells = <1>; | ||
108 | }; | ||
109 | |||
110 | rst: reset-controller@1806001c { | ||
111 | compatible = "qca,ar7100-reset"; | ||
112 | reg = <0x1806001c 0x4>; | ||
113 | |||
114 | #reset-cells = <1>; | ||
115 | }; | ||
116 | }; | ||
117 | |||
118 | usb: usb@1b000100 { | ||
119 | compatible = "chipidea,usb2"; | ||
120 | reg = <0x1b000000 0x200>; | ||
121 | |||
122 | interrupts = <3>; | ||
123 | resets = <&rst 5>; | ||
124 | |||
125 | phy-names = "usb-phy"; | ||
126 | phys = <&usb_phy>; | ||
127 | |||
128 | status = "disabled"; | ||
129 | }; | ||
130 | |||
131 | spi: spi@1f000000 { | ||
132 | compatible = "qca,ar7100-spi"; | ||
133 | reg = <0x1f000000 0x10>; | ||
134 | |||
135 | clocks = <&pll ATH79_CLK_AHB>; | ||
136 | clock-names = "ahb"; | ||
137 | |||
138 | #address-cells = <1>; | ||
139 | #size-cells = <0>; | ||
140 | |||
141 | status = "disabled"; | ||
142 | }; | ||
143 | }; | ||
144 | |||
145 | usb_phy: usb-phy { | ||
146 | compatible = "qca,ar7100-usb-phy"; | ||
147 | |||
148 | reset-names = "usb-phy", "usb-suspend-override"; | ||
149 | resets = <&rst 4>, <&rst 3>; | ||
150 | |||
151 | #phy-cells = <0>; | ||
152 | |||
153 | status = "disabled"; | ||
154 | }; | ||
155 | }; | ||
diff --git a/arch/mips/boot/dts/qca/ar9331_dpt_module.dts b/arch/mips/boot/dts/qca/ar9331_dpt_module.dts new file mode 100644 index 000000000000..98e74500e79d --- /dev/null +++ b/arch/mips/boot/dts/qca/ar9331_dpt_module.dts | |||
@@ -0,0 +1,78 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | #include <dt-bindings/gpio/gpio.h> | ||
4 | #include <dt-bindings/input/input.h> | ||
5 | |||
6 | #include "ar9331.dtsi" | ||
7 | |||
8 | / { | ||
9 | model = "DPTechnics DPT-Module"; | ||
10 | compatible = "dptechnics,dpt-module"; | ||
11 | |||
12 | aliases { | ||
13 | serial0 = &uart; | ||
14 | }; | ||
15 | |||
16 | memory@0 { | ||
17 | device_type = "memory"; | ||
18 | reg = <0x0 0x4000000>; | ||
19 | }; | ||
20 | |||
21 | leds { | ||
22 | compatible = "gpio-leds"; | ||
23 | |||
24 | system { | ||
25 | label = "dpt-module:green:system"; | ||
26 | gpios = <&gpio 27 GPIO_ACTIVE_LOW>; | ||
27 | default-state = "off"; | ||
28 | }; | ||
29 | }; | ||
30 | |||
31 | gpio-keys-polled { | ||
32 | compatible = "gpio-keys-polled"; | ||
33 | #address-cells = <1>; | ||
34 | #size-cells = <0>; | ||
35 | poll-interval = <100>; | ||
36 | |||
37 | button@0 { | ||
38 | label = "reset"; | ||
39 | linux,code = <KEY_RESTART>; | ||
40 | gpios = <&gpio 11 GPIO_ACTIVE_LOW>; | ||
41 | }; | ||
42 | }; | ||
43 | }; | ||
44 | |||
45 | &ref { | ||
46 | clock-frequency = <25000000>; | ||
47 | }; | ||
48 | |||
49 | &uart { | ||
50 | status = "okay"; | ||
51 | }; | ||
52 | |||
53 | &gpio { | ||
54 | status = "okay"; | ||
55 | }; | ||
56 | |||
57 | &usb { | ||
58 | dr_mode = "host"; | ||
59 | status = "okay"; | ||
60 | }; | ||
61 | |||
62 | &usb_phy { | ||
63 | status = "okay"; | ||
64 | }; | ||
65 | |||
66 | &spi { | ||
67 | num-chipselects = <1>; | ||
68 | status = "okay"; | ||
69 | |||
70 | /* Winbond 25Q128FVSG SPI flash */ | ||
71 | spiflash: w25q128@0 { | ||
72 | #address-cells = <1>; | ||
73 | #size-cells = <1>; | ||
74 | compatible = "winbond,w25q128", "jedec,spi-nor"; | ||
75 | spi-max-frequency = <104000000>; | ||
76 | reg = <0>; | ||
77 | }; | ||
78 | }; | ||
diff --git a/arch/mips/boot/dts/qca/ar9331_dragino_ms14.dts b/arch/mips/boot/dts/qca/ar9331_dragino_ms14.dts new file mode 100644 index 000000000000..56f832076a69 --- /dev/null +++ b/arch/mips/boot/dts/qca/ar9331_dragino_ms14.dts | |||
@@ -0,0 +1,102 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | #include <dt-bindings/gpio/gpio.h> | ||
4 | #include <dt-bindings/input/input.h> | ||
5 | |||
6 | #include "ar9331.dtsi" | ||
7 | |||
8 | / { | ||
9 | model = "Dragino MS14 (Dragino 2)"; | ||
10 | compatible = "dragino,ms14"; | ||
11 | |||
12 | aliases { | ||
13 | serial0 = &uart; | ||
14 | }; | ||
15 | |||
16 | memory@0 { | ||
17 | device_type = "memory"; | ||
18 | reg = <0x0 0x4000000>; | ||
19 | }; | ||
20 | |||
21 | leds { | ||
22 | compatible = "gpio-leds"; | ||
23 | |||
24 | wlan { | ||
25 | label = "dragino2:red:wlan"; | ||
26 | gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; | ||
27 | default-state = "off"; | ||
28 | }; | ||
29 | |||
30 | lan { | ||
31 | label = "dragino2:red:lan"; | ||
32 | gpios = <&gpio 13 GPIO_ACTIVE_LOW>; | ||
33 | default-state = "off"; | ||
34 | }; | ||
35 | |||
36 | wan { | ||
37 | label = "dragino2:red:wan"; | ||
38 | gpios = <&gpio 17 GPIO_ACTIVE_LOW>; | ||
39 | default-state = "off"; | ||
40 | }; | ||
41 | |||
42 | system { | ||
43 | label = "dragino2:red:system"; | ||
44 | gpios = <&gpio 28 GPIO_ACTIVE_HIGH>; | ||
45 | default-state = "off"; | ||
46 | }; | ||
47 | }; | ||
48 | |||
49 | gpio-keys-polled { | ||
50 | compatible = "gpio-keys-polled"; | ||
51 | #address-cells = <1>; | ||
52 | #size-cells = <0>; | ||
53 | poll-interval = <100>; | ||
54 | |||
55 | button@0 { | ||
56 | label = "jumpstart"; | ||
57 | linux,code = <KEY_WPS_BUTTON>; | ||
58 | gpios = <&gpio 11 GPIO_ACTIVE_LOW>; | ||
59 | }; | ||
60 | |||
61 | button@1 { | ||
62 | label = "reset"; | ||
63 | linux,code = <KEY_RESTART>; | ||
64 | gpios = <&gpio 12 GPIO_ACTIVE_LOW>; | ||
65 | }; | ||
66 | }; | ||
67 | }; | ||
68 | |||
69 | &ref { | ||
70 | clock-frequency = <25000000>; | ||
71 | }; | ||
72 | |||
73 | &uart { | ||
74 | status = "okay"; | ||
75 | }; | ||
76 | |||
77 | &gpio { | ||
78 | status = "okay"; | ||
79 | }; | ||
80 | |||
81 | &usb { | ||
82 | dr_mode = "host"; | ||
83 | status = "okay"; | ||
84 | }; | ||
85 | |||
86 | &usb_phy { | ||
87 | status = "okay"; | ||
88 | }; | ||
89 | |||
90 | &spi { | ||
91 | num-chipselects = <1>; | ||
92 | status = "okay"; | ||
93 | |||
94 | /* Winbond 25Q128BVFG SPI flash */ | ||
95 | spiflash: w25q128@0 { | ||
96 | #address-cells = <1>; | ||
97 | #size-cells = <1>; | ||
98 | compatible = "winbond,w25q128", "jedec,spi-nor"; | ||
99 | spi-max-frequency = <104000000>; | ||
100 | reg = <0>; | ||
101 | }; | ||
102 | }; | ||
diff --git a/arch/mips/boot/dts/qca/ar9331_omega.dts b/arch/mips/boot/dts/qca/ar9331_omega.dts new file mode 100644 index 000000000000..b2be3b04479d --- /dev/null +++ b/arch/mips/boot/dts/qca/ar9331_omega.dts | |||
@@ -0,0 +1,78 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | #include <dt-bindings/gpio/gpio.h> | ||
4 | #include <dt-bindings/input/input.h> | ||
5 | |||
6 | #include "ar9331.dtsi" | ||
7 | |||
8 | / { | ||
9 | model = "Onion Omega"; | ||
10 | compatible = "onion,omega"; | ||
11 | |||
12 | aliases { | ||
13 | serial0 = &uart; | ||
14 | }; | ||
15 | |||
16 | memory@0 { | ||
17 | device_type = "memory"; | ||
18 | reg = <0x0 0x4000000>; | ||
19 | }; | ||
20 | |||
21 | leds { | ||
22 | compatible = "gpio-leds"; | ||
23 | |||
24 | system { | ||
25 | label = "onion:amber:system"; | ||
26 | gpios = <&gpio 27 GPIO_ACTIVE_LOW>; | ||
27 | default-state = "off"; | ||
28 | }; | ||
29 | }; | ||
30 | |||
31 | gpio-keys-polled { | ||
32 | compatible = "gpio-keys-polled"; | ||
33 | #address-cells = <1>; | ||
34 | #size-cells = <0>; | ||
35 | poll-interval = <100>; | ||
36 | |||
37 | button@0 { | ||
38 | label = "reset"; | ||
39 | linux,code = <KEY_RESTART>; | ||
40 | gpios = <&gpio 11 GPIO_ACTIVE_HIGH>; | ||
41 | }; | ||
42 | }; | ||
43 | }; | ||
44 | |||
45 | &ref { | ||
46 | clock-frequency = <25000000>; | ||
47 | }; | ||
48 | |||
49 | &uart { | ||
50 | status = "okay"; | ||
51 | }; | ||
52 | |||
53 | &gpio { | ||
54 | status = "okay"; | ||
55 | }; | ||
56 | |||
57 | &usb { | ||
58 | dr_mode = "host"; | ||
59 | status = "okay"; | ||
60 | }; | ||
61 | |||
62 | &usb_phy { | ||
63 | status = "okay"; | ||
64 | }; | ||
65 | |||
66 | &spi { | ||
67 | num-chipselects = <1>; | ||
68 | status = "okay"; | ||
69 | |||
70 | /* Winbond 25Q128FVSG SPI flash */ | ||
71 | spiflash: w25q128@0 { | ||
72 | #address-cells = <1>; | ||
73 | #size-cells = <1>; | ||
74 | compatible = "winbond,w25q128", "jedec,spi-nor"; | ||
75 | spi-max-frequency = <104000000>; | ||
76 | reg = <0>; | ||
77 | }; | ||
78 | }; | ||
diff --git a/arch/mips/boot/dts/qca/ar9331_tl_mr3020.dts b/arch/mips/boot/dts/qca/ar9331_tl_mr3020.dts new file mode 100644 index 000000000000..919cf3b854a5 --- /dev/null +++ b/arch/mips/boot/dts/qca/ar9331_tl_mr3020.dts | |||
@@ -0,0 +1,118 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | #include <dt-bindings/gpio/gpio.h> | ||
4 | #include <dt-bindings/input/input.h> | ||
5 | |||
6 | #include "ar9331.dtsi" | ||
7 | |||
8 | / { | ||
9 | model = "TP-Link TL-MR3020"; | ||
10 | compatible = "tplink,tl-mr3020"; | ||
11 | |||
12 | aliases { | ||
13 | serial0 = &uart; | ||
14 | }; | ||
15 | |||
16 | memory@0 { | ||
17 | device_type = "memory"; | ||
18 | reg = <0x0 0x2000000>; | ||
19 | }; | ||
20 | |||
21 | leds { | ||
22 | compatible = "gpio-leds"; | ||
23 | |||
24 | wlan { | ||
25 | label = "tp-link:green:wlan"; | ||
26 | gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; | ||
27 | default-state = "off"; | ||
28 | }; | ||
29 | |||
30 | lan { | ||
31 | label = "tp-link:green:lan"; | ||
32 | gpios = <&gpio 17 GPIO_ACTIVE_LOW>; | ||
33 | default-state = "off"; | ||
34 | }; | ||
35 | |||
36 | wps { | ||
37 | label = "tp-link:green:wps"; | ||
38 | gpios = <&gpio 26 GPIO_ACTIVE_LOW>; | ||
39 | default-state = "off"; | ||
40 | }; | ||
41 | |||
42 | led3g { | ||
43 | label = "tp-link:green:3g"; | ||
44 | gpios = <&gpio 27 GPIO_ACTIVE_LOW>; | ||
45 | default-state = "off"; | ||
46 | }; | ||
47 | }; | ||
48 | |||
49 | gpio-keys-polled { | ||
50 | compatible = "gpio-keys-polled"; | ||
51 | #address-cells = <1>; | ||
52 | #size-cells = <0>; | ||
53 | poll-interval = <100>; | ||
54 | |||
55 | button@0 { | ||
56 | label = "wps"; | ||
57 | linux,code = <KEY_WPS_BUTTON>; | ||
58 | gpios = <&gpio 11 GPIO_ACTIVE_HIGH>; | ||
59 | }; | ||
60 | |||
61 | button@1 { | ||
62 | label = "sw1"; | ||
63 | linux,code = <BTN_0>; | ||
64 | gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; | ||
65 | }; | ||
66 | |||
67 | button@2 { | ||
68 | label = "sw2"; | ||
69 | linux,code = <BTN_1>; | ||
70 | gpios = <&gpio 20 GPIO_ACTIVE_HIGH>; | ||
71 | }; | ||
72 | }; | ||
73 | |||
74 | reg_usb_vbus: reg_usb_vbus { | ||
75 | compatible = "regulator-fixed"; | ||
76 | regulator-name = "usb_vbus"; | ||
77 | regulator-min-microvolt = <5000000>; | ||
78 | regulator-max-microvolt = <5000000>; | ||
79 | gpio = <&gpio 8 GPIO_ACTIVE_HIGH>; | ||
80 | enable-active-high; | ||
81 | }; | ||
82 | }; | ||
83 | |||
84 | &ref { | ||
85 | clock-frequency = <25000000>; | ||
86 | }; | ||
87 | |||
88 | &uart { | ||
89 | status = "okay"; | ||
90 | }; | ||
91 | |||
92 | &gpio { | ||
93 | status = "okay"; | ||
94 | }; | ||
95 | |||
96 | &usb { | ||
97 | dr_mode = "host"; | ||
98 | vbus-supply = <®_usb_vbus>; | ||
99 | status = "okay"; | ||
100 | }; | ||
101 | |||
102 | &usb_phy { | ||
103 | status = "okay"; | ||
104 | }; | ||
105 | |||
106 | &spi { | ||
107 | num-chipselects = <1>; | ||
108 | status = "okay"; | ||
109 | |||
110 | /* Spansion S25FL032PIF SPI flash */ | ||
111 | spiflash: s25sl032p@0 { | ||
112 | #address-cells = <1>; | ||
113 | #size-cells = <1>; | ||
114 | compatible = "spansion,s25sl032p", "jedec,spi-nor"; | ||
115 | spi-max-frequency = <104000000>; | ||
116 | reg = <0>; | ||
117 | }; | ||
118 | }; | ||
diff --git a/arch/mips/boot/tools/.gitignore b/arch/mips/boot/tools/.gitignore new file mode 100644 index 000000000000..be0ed065249b --- /dev/null +++ b/arch/mips/boot/tools/.gitignore | |||
@@ -0,0 +1 @@ | |||
relocs | |||
diff --git a/arch/mips/boot/tools/Makefile b/arch/mips/boot/tools/Makefile new file mode 100644 index 000000000000..d232a68f6c8a --- /dev/null +++ b/arch/mips/boot/tools/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | |||
2 | hostprogs-y += relocs | ||
3 | relocs-objs += relocs_32.o | ||
4 | relocs-objs += relocs_64.o | ||
5 | relocs-objs += relocs_main.o | ||
6 | PHONY += relocs | ||
7 | relocs: $(obj)/relocs | ||
8 | @: | ||
diff --git a/arch/mips/boot/tools/relocs.c b/arch/mips/boot/tools/relocs.c new file mode 100644 index 000000000000..b9cbf78527e8 --- /dev/null +++ b/arch/mips/boot/tools/relocs.c | |||
@@ -0,0 +1,680 @@ | |||
1 | /* This is included from relocs_32/64.c */ | ||
2 | |||
3 | #define ElfW(type) _ElfW(ELF_BITS, type) | ||
4 | #define _ElfW(bits, type) __ElfW(bits, type) | ||
5 | #define __ElfW(bits, type) Elf##bits##_##type | ||
6 | |||
7 | #define Elf_Addr ElfW(Addr) | ||
8 | #define Elf_Ehdr ElfW(Ehdr) | ||
9 | #define Elf_Phdr ElfW(Phdr) | ||
10 | #define Elf_Shdr ElfW(Shdr) | ||
11 | #define Elf_Sym ElfW(Sym) | ||
12 | |||
13 | static Elf_Ehdr ehdr; | ||
14 | |||
15 | struct relocs { | ||
16 | uint32_t *offset; | ||
17 | unsigned long count; | ||
18 | unsigned long size; | ||
19 | }; | ||
20 | |||
21 | static struct relocs relocs; | ||
22 | |||
23 | struct section { | ||
24 | Elf_Shdr shdr; | ||
25 | struct section *link; | ||
26 | Elf_Sym *symtab; | ||
27 | Elf_Rel *reltab; | ||
28 | char *strtab; | ||
29 | long shdr_offset; | ||
30 | }; | ||
31 | static struct section *secs; | ||
32 | |||
33 | static const char * const regex_sym_kernel = { | ||
34 | /* Symbols matching these regex's should never be relocated */ | ||
35 | "^(__crc_)", | ||
36 | }; | ||
37 | |||
38 | static regex_t sym_regex_c; | ||
39 | |||
40 | static int regex_skip_reloc(const char *sym_name) | ||
41 | { | ||
42 | return !regexec(&sym_regex_c, sym_name, 0, NULL, 0); | ||
43 | } | ||
44 | |||
45 | static void regex_init(void) | ||
46 | { | ||
47 | char errbuf[128]; | ||
48 | int err; | ||
49 | |||
50 | err = regcomp(&sym_regex_c, regex_sym_kernel, | ||
51 | REG_EXTENDED|REG_NOSUB); | ||
52 | |||
53 | if (err) { | ||
54 | regerror(err, &sym_regex_c, errbuf, sizeof(errbuf)); | ||
55 | die("%s", errbuf); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | static const char *rel_type(unsigned type) | ||
60 | { | ||
61 | static const char * const type_name[] = { | ||
62 | #define REL_TYPE(X)[X] = #X | ||
63 | REL_TYPE(R_MIPS_NONE), | ||
64 | REL_TYPE(R_MIPS_16), | ||
65 | REL_TYPE(R_MIPS_32), | ||
66 | REL_TYPE(R_MIPS_REL32), | ||
67 | REL_TYPE(R_MIPS_26), | ||
68 | REL_TYPE(R_MIPS_HI16), | ||
69 | REL_TYPE(R_MIPS_LO16), | ||
70 | REL_TYPE(R_MIPS_GPREL16), | ||
71 | REL_TYPE(R_MIPS_LITERAL), | ||
72 | REL_TYPE(R_MIPS_GOT16), | ||
73 | REL_TYPE(R_MIPS_PC16), | ||
74 | REL_TYPE(R_MIPS_CALL16), | ||
75 | REL_TYPE(R_MIPS_GPREL32), | ||
76 | REL_TYPE(R_MIPS_64), | ||
77 | REL_TYPE(R_MIPS_HIGHER), | ||
78 | REL_TYPE(R_MIPS_HIGHEST), | ||
79 | REL_TYPE(R_MIPS_PC21_S2), | ||
80 | REL_TYPE(R_MIPS_PC26_S2), | ||
81 | #undef REL_TYPE | ||
82 | }; | ||
83 | const char *name = "unknown type rel type name"; | ||
84 | |||
85 | if (type < ARRAY_SIZE(type_name) && type_name[type]) | ||
86 | name = type_name[type]; | ||
87 | return name; | ||
88 | } | ||
89 | |||
90 | static const char *sec_name(unsigned shndx) | ||
91 | { | ||
92 | const char *sec_strtab; | ||
93 | const char *name; | ||
94 | |||
95 | sec_strtab = secs[ehdr.e_shstrndx].strtab; | ||
96 | if (shndx < ehdr.e_shnum) | ||
97 | name = sec_strtab + secs[shndx].shdr.sh_name; | ||
98 | else if (shndx == SHN_ABS) | ||
99 | name = "ABSOLUTE"; | ||
100 | else if (shndx == SHN_COMMON) | ||
101 | name = "COMMON"; | ||
102 | else | ||
103 | name = "<noname>"; | ||
104 | return name; | ||
105 | } | ||
106 | |||
107 | static struct section *sec_lookup(const char *secname) | ||
108 | { | ||
109 | int i; | ||
110 | |||
111 | for (i = 0; i < ehdr.e_shnum; i++) | ||
112 | if (strcmp(secname, sec_name(i)) == 0) | ||
113 | return &secs[i]; | ||
114 | |||
115 | return NULL; | ||
116 | } | ||
117 | |||
118 | static const char *sym_name(const char *sym_strtab, Elf_Sym *sym) | ||
119 | { | ||
120 | const char *name; | ||
121 | |||
122 | if (sym->st_name) | ||
123 | name = sym_strtab + sym->st_name; | ||
124 | else | ||
125 | name = sec_name(sym->st_shndx); | ||
126 | return name; | ||
127 | } | ||
128 | |||
129 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
130 | #define le16_to_cpu(val) (val) | ||
131 | #define le32_to_cpu(val) (val) | ||
132 | #define le64_to_cpu(val) (val) | ||
133 | #define be16_to_cpu(val) bswap_16(val) | ||
134 | #define be32_to_cpu(val) bswap_32(val) | ||
135 | #define be64_to_cpu(val) bswap_64(val) | ||
136 | |||
137 | #define cpu_to_le16(val) (val) | ||
138 | #define cpu_to_le32(val) (val) | ||
139 | #define cpu_to_le64(val) (val) | ||
140 | #define cpu_to_be16(val) bswap_16(val) | ||
141 | #define cpu_to_be32(val) bswap_32(val) | ||
142 | #define cpu_to_be64(val) bswap_64(val) | ||
143 | #endif | ||
144 | #if BYTE_ORDER == BIG_ENDIAN | ||
145 | #define le16_to_cpu(val) bswap_16(val) | ||
146 | #define le32_to_cpu(val) bswap_32(val) | ||
147 | #define le64_to_cpu(val) bswap_64(val) | ||
148 | #define be16_to_cpu(val) (val) | ||
149 | #define be32_to_cpu(val) (val) | ||
150 | #define be64_to_cpu(val) (val) | ||
151 | |||
152 | #define cpu_to_le16(val) bswap_16(val) | ||
153 | #define cpu_to_le32(val) bswap_32(val) | ||
154 | #define cpu_to_le64(val) bswap_64(val) | ||
155 | #define cpu_to_be16(val) (val) | ||
156 | #define cpu_to_be32(val) (val) | ||
157 | #define cpu_to_be64(val) (val) | ||
158 | #endif | ||
159 | |||
160 | static uint16_t elf16_to_cpu(uint16_t val) | ||
161 | { | ||
162 | if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) | ||
163 | return le16_to_cpu(val); | ||
164 | else | ||
165 | return be16_to_cpu(val); | ||
166 | } | ||
167 | |||
168 | static uint32_t elf32_to_cpu(uint32_t val) | ||
169 | { | ||
170 | if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) | ||
171 | return le32_to_cpu(val); | ||
172 | else | ||
173 | return be32_to_cpu(val); | ||
174 | } | ||
175 | |||
176 | static uint32_t cpu_to_elf32(uint32_t val) | ||
177 | { | ||
178 | if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) | ||
179 | return cpu_to_le32(val); | ||
180 | else | ||
181 | return cpu_to_be32(val); | ||
182 | } | ||
183 | |||
184 | #define elf_half_to_cpu(x) elf16_to_cpu(x) | ||
185 | #define elf_word_to_cpu(x) elf32_to_cpu(x) | ||
186 | |||
187 | #if ELF_BITS == 64 | ||
188 | static uint64_t elf64_to_cpu(uint64_t val) | ||
189 | { | ||
190 | if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) | ||
191 | return le64_to_cpu(val); | ||
192 | else | ||
193 | return be64_to_cpu(val); | ||
194 | } | ||
195 | #define elf_addr_to_cpu(x) elf64_to_cpu(x) | ||
196 | #define elf_off_to_cpu(x) elf64_to_cpu(x) | ||
197 | #define elf_xword_to_cpu(x) elf64_to_cpu(x) | ||
198 | #else | ||
199 | #define elf_addr_to_cpu(x) elf32_to_cpu(x) | ||
200 | #define elf_off_to_cpu(x) elf32_to_cpu(x) | ||
201 | #define elf_xword_to_cpu(x) elf32_to_cpu(x) | ||
202 | #endif | ||
203 | |||
204 | static void read_ehdr(FILE *fp) | ||
205 | { | ||
206 | if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) | ||
207 | die("Cannot read ELF header: %s\n", strerror(errno)); | ||
208 | |||
209 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) | ||
210 | die("No ELF magic\n"); | ||
211 | |||
212 | if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) | ||
213 | die("Not a %d bit executable\n", ELF_BITS); | ||
214 | |||
215 | if ((ehdr.e_ident[EI_DATA] != ELFDATA2LSB) && | ||
216 | (ehdr.e_ident[EI_DATA] != ELFDATA2MSB)) | ||
217 | die("Unknown ELF Endianness\n"); | ||
218 | |||
219 | if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) | ||
220 | die("Unknown ELF version\n"); | ||
221 | |||
222 | /* Convert the fields to native endian */ | ||
223 | ehdr.e_type = elf_half_to_cpu(ehdr.e_type); | ||
224 | ehdr.e_machine = elf_half_to_cpu(ehdr.e_machine); | ||
225 | ehdr.e_version = elf_word_to_cpu(ehdr.e_version); | ||
226 | ehdr.e_entry = elf_addr_to_cpu(ehdr.e_entry); | ||
227 | ehdr.e_phoff = elf_off_to_cpu(ehdr.e_phoff); | ||
228 | ehdr.e_shoff = elf_off_to_cpu(ehdr.e_shoff); | ||
229 | ehdr.e_flags = elf_word_to_cpu(ehdr.e_flags); | ||
230 | ehdr.e_ehsize = elf_half_to_cpu(ehdr.e_ehsize); | ||
231 | ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize); | ||
232 | ehdr.e_phnum = elf_half_to_cpu(ehdr.e_phnum); | ||
233 | ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize); | ||
234 | ehdr.e_shnum = elf_half_to_cpu(ehdr.e_shnum); | ||
235 | ehdr.e_shstrndx = elf_half_to_cpu(ehdr.e_shstrndx); | ||
236 | |||
237 | if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) | ||
238 | die("Unsupported ELF header type\n"); | ||
239 | |||
240 | if (ehdr.e_machine != ELF_MACHINE) | ||
241 | die("Not for %s\n", ELF_MACHINE_NAME); | ||
242 | |||
243 | if (ehdr.e_version != EV_CURRENT) | ||
244 | die("Unknown ELF version\n"); | ||
245 | |||
246 | if (ehdr.e_ehsize != sizeof(Elf_Ehdr)) | ||
247 | die("Bad Elf header size\n"); | ||
248 | |||
249 | if (ehdr.e_phentsize != sizeof(Elf_Phdr)) | ||
250 | die("Bad program header entry\n"); | ||
251 | |||
252 | if (ehdr.e_shentsize != sizeof(Elf_Shdr)) | ||
253 | die("Bad section header entry\n"); | ||
254 | |||
255 | if (ehdr.e_shstrndx >= ehdr.e_shnum) | ||
256 | die("String table index out of bounds\n"); | ||
257 | } | ||
258 | |||
259 | static void read_shdrs(FILE *fp) | ||
260 | { | ||
261 | int i; | ||
262 | Elf_Shdr shdr; | ||
263 | |||
264 | secs = calloc(ehdr.e_shnum, sizeof(struct section)); | ||
265 | if (!secs) | ||
266 | die("Unable to allocate %d section headers\n", ehdr.e_shnum); | ||
267 | |||
268 | if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) | ||
269 | die("Seek to %d failed: %s\n", ehdr.e_shoff, strerror(errno)); | ||
270 | |||
271 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
272 | struct section *sec = &secs[i]; | ||
273 | |||
274 | sec->shdr_offset = ftell(fp); | ||
275 | if (fread(&shdr, sizeof(shdr), 1, fp) != 1) | ||
276 | die("Cannot read ELF section headers %d/%d: %s\n", | ||
277 | i, ehdr.e_shnum, strerror(errno)); | ||
278 | sec->shdr.sh_name = elf_word_to_cpu(shdr.sh_name); | ||
279 | sec->shdr.sh_type = elf_word_to_cpu(shdr.sh_type); | ||
280 | sec->shdr.sh_flags = elf_xword_to_cpu(shdr.sh_flags); | ||
281 | sec->shdr.sh_addr = elf_addr_to_cpu(shdr.sh_addr); | ||
282 | sec->shdr.sh_offset = elf_off_to_cpu(shdr.sh_offset); | ||
283 | sec->shdr.sh_size = elf_xword_to_cpu(shdr.sh_size); | ||
284 | sec->shdr.sh_link = elf_word_to_cpu(shdr.sh_link); | ||
285 | sec->shdr.sh_info = elf_word_to_cpu(shdr.sh_info); | ||
286 | sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign); | ||
287 | sec->shdr.sh_entsize = elf_xword_to_cpu(shdr.sh_entsize); | ||
288 | if (sec->shdr.sh_link < ehdr.e_shnum) | ||
289 | sec->link = &secs[sec->shdr.sh_link]; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | static void read_strtabs(FILE *fp) | ||
294 | { | ||
295 | int i; | ||
296 | |||
297 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
298 | struct section *sec = &secs[i]; | ||
299 | |||
300 | if (sec->shdr.sh_type != SHT_STRTAB) | ||
301 | continue; | ||
302 | |||
303 | sec->strtab = malloc(sec->shdr.sh_size); | ||
304 | if (!sec->strtab) | ||
305 | die("malloc of %d bytes for strtab failed\n", | ||
306 | sec->shdr.sh_size); | ||
307 | |||
308 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) | ||
309 | die("Seek to %d failed: %s\n", | ||
310 | sec->shdr.sh_offset, strerror(errno)); | ||
311 | |||
312 | if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) != | ||
313 | sec->shdr.sh_size) | ||
314 | die("Cannot read symbol table: %s\n", strerror(errno)); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | static void read_symtabs(FILE *fp) | ||
319 | { | ||
320 | int i, j; | ||
321 | |||
322 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
323 | struct section *sec = &secs[i]; | ||
324 | if (sec->shdr.sh_type != SHT_SYMTAB) | ||
325 | continue; | ||
326 | |||
327 | sec->symtab = malloc(sec->shdr.sh_size); | ||
328 | if (!sec->symtab) | ||
329 | die("malloc of %d bytes for symtab failed\n", | ||
330 | sec->shdr.sh_size); | ||
331 | |||
332 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) | ||
333 | die("Seek to %d failed: %s\n", | ||
334 | sec->shdr.sh_offset, strerror(errno)); | ||
335 | |||
336 | if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) != | ||
337 | sec->shdr.sh_size) | ||
338 | die("Cannot read symbol table: %s\n", strerror(errno)); | ||
339 | |||
340 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) { | ||
341 | Elf_Sym *sym = &sec->symtab[j]; | ||
342 | |||
343 | sym->st_name = elf_word_to_cpu(sym->st_name); | ||
344 | sym->st_value = elf_addr_to_cpu(sym->st_value); | ||
345 | sym->st_size = elf_xword_to_cpu(sym->st_size); | ||
346 | sym->st_shndx = elf_half_to_cpu(sym->st_shndx); | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | static void read_relocs(FILE *fp) | ||
352 | { | ||
353 | static unsigned long base = 0; | ||
354 | int i, j; | ||
355 | |||
356 | if (!base) { | ||
357 | struct section *sec = sec_lookup(".text"); | ||
358 | |||
359 | if (!sec) | ||
360 | die("Could not find .text section\n"); | ||
361 | |||
362 | base = sec->shdr.sh_addr; | ||
363 | } | ||
364 | |||
365 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
366 | struct section *sec = &secs[i]; | ||
367 | |||
368 | if (sec->shdr.sh_type != SHT_REL_TYPE) | ||
369 | continue; | ||
370 | |||
371 | sec->reltab = malloc(sec->shdr.sh_size); | ||
372 | if (!sec->reltab) | ||
373 | die("malloc of %d bytes for relocs failed\n", | ||
374 | sec->shdr.sh_size); | ||
375 | |||
376 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) | ||
377 | die("Seek to %d failed: %s\n", | ||
378 | sec->shdr.sh_offset, strerror(errno)); | ||
379 | |||
380 | if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) != | ||
381 | sec->shdr.sh_size) | ||
382 | die("Cannot read symbol table: %s\n", strerror(errno)); | ||
383 | |||
384 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) { | ||
385 | Elf_Rel *rel = &sec->reltab[j]; | ||
386 | |||
387 | rel->r_offset = elf_addr_to_cpu(rel->r_offset); | ||
388 | /* Set offset into kernel image */ | ||
389 | rel->r_offset -= base; | ||
390 | #if (ELF_BITS == 32) | ||
391 | rel->r_info = elf_xword_to_cpu(rel->r_info); | ||
392 | #else | ||
393 | /* Convert MIPS64 RELA format - only the symbol | ||
394 | * index needs converting to native endianness | ||
395 | */ | ||
396 | rel->r_info = rel->r_info; | ||
397 | ELF_R_SYM(rel->r_info) = elf32_to_cpu(ELF_R_SYM(rel->r_info)); | ||
398 | #endif | ||
399 | #if (SHT_REL_TYPE == SHT_RELA) | ||
400 | rel->r_addend = elf_xword_to_cpu(rel->r_addend); | ||
401 | #endif | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | |||
406 | static void remove_relocs(FILE *fp) | ||
407 | { | ||
408 | int i; | ||
409 | Elf_Shdr shdr; | ||
410 | |||
411 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
412 | struct section *sec = &secs[i]; | ||
413 | |||
414 | if (sec->shdr.sh_type != SHT_REL_TYPE) | ||
415 | continue; | ||
416 | |||
417 | if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0) | ||
418 | die("Seek to %d failed: %s\n", | ||
419 | sec->shdr_offset, strerror(errno)); | ||
420 | |||
421 | if (fread(&shdr, sizeof(shdr), 1, fp) != 1) | ||
422 | die("Cannot read ELF section headers %d/%d: %s\n", | ||
423 | i, ehdr.e_shnum, strerror(errno)); | ||
424 | |||
425 | /* Set relocation section size to 0, effectively removing it. | ||
426 | * This is necessary due to lack of support for relocations | ||
427 | * in objcopy when creating 32bit elf from 64bit elf. | ||
428 | */ | ||
429 | shdr.sh_size = 0; | ||
430 | |||
431 | if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0) | ||
432 | die("Seek to %d failed: %s\n", | ||
433 | sec->shdr_offset, strerror(errno)); | ||
434 | |||
435 | if (fwrite(&shdr, sizeof(shdr), 1, fp) != 1) | ||
436 | die("Cannot write ELF section headers %d/%d: %s\n", | ||
437 | i, ehdr.e_shnum, strerror(errno)); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | static void add_reloc(struct relocs *r, uint32_t offset, unsigned type) | ||
442 | { | ||
443 | /* Relocation representation in binary table: | ||
444 | * |76543210|76543210|76543210|76543210| | ||
445 | * | Type | offset from _text >> 2 | | ||
446 | */ | ||
447 | offset >>= 2; | ||
448 | if (offset > 0x00FFFFFF) | ||
449 | die("Kernel image exceeds maximum size for relocation!\n"); | ||
450 | |||
451 | offset = (offset & 0x00FFFFFF) | ((type & 0xFF) << 24); | ||
452 | |||
453 | if (r->count == r->size) { | ||
454 | unsigned long newsize = r->size + 50000; | ||
455 | void *mem = realloc(r->offset, newsize * sizeof(r->offset[0])); | ||
456 | |||
457 | if (!mem) | ||
458 | die("realloc failed\n"); | ||
459 | |||
460 | r->offset = mem; | ||
461 | r->size = newsize; | ||
462 | } | ||
463 | r->offset[r->count++] = offset; | ||
464 | } | ||
465 | |||
466 | static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel, | ||
467 | Elf_Sym *sym, const char *symname)) | ||
468 | { | ||
469 | int i; | ||
470 | |||
471 | /* Walk through the relocations */ | ||
472 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
473 | char *sym_strtab; | ||
474 | Elf_Sym *sh_symtab; | ||
475 | struct section *sec_applies, *sec_symtab; | ||
476 | int j; | ||
477 | struct section *sec = &secs[i]; | ||
478 | |||
479 | if (sec->shdr.sh_type != SHT_REL_TYPE) | ||
480 | continue; | ||
481 | |||
482 | sec_symtab = sec->link; | ||
483 | sec_applies = &secs[sec->shdr.sh_info]; | ||
484 | if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) | ||
485 | continue; | ||
486 | |||
487 | sh_symtab = sec_symtab->symtab; | ||
488 | sym_strtab = sec_symtab->link->strtab; | ||
489 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) { | ||
490 | Elf_Rel *rel = &sec->reltab[j]; | ||
491 | Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)]; | ||
492 | const char *symname = sym_name(sym_strtab, sym); | ||
493 | |||
494 | process(sec, rel, sym, symname); | ||
495 | } | ||
496 | } | ||
497 | } | ||
498 | |||
499 | static int do_reloc(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, | ||
500 | const char *symname) | ||
501 | { | ||
502 | unsigned r_type = ELF_R_TYPE(rel->r_info); | ||
503 | unsigned bind = ELF_ST_BIND(sym->st_info); | ||
504 | |||
505 | if ((bind == STB_WEAK) && (sym->st_value == 0)) { | ||
506 | /* Don't relocate weak symbols without a target */ | ||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | if (regex_skip_reloc(symname)) | ||
511 | return 0; | ||
512 | |||
513 | switch (r_type) { | ||
514 | case R_MIPS_NONE: | ||
515 | case R_MIPS_REL32: | ||
516 | case R_MIPS_PC16: | ||
517 | case R_MIPS_PC21_S2: | ||
518 | case R_MIPS_PC26_S2: | ||
519 | /* | ||
520 | * NONE can be ignored and PC relative relocations don't | ||
521 | * need to be adjusted. | ||
522 | */ | ||
523 | case R_MIPS_HIGHEST: | ||
524 | case R_MIPS_HIGHER: | ||
525 | /* We support relocating within the same 4Gb segment only, | ||
526 | * thus leaving the top 32bits unchanged | ||
527 | */ | ||
528 | case R_MIPS_LO16: | ||
529 | /* We support relocating by 64k jumps only | ||
530 | * thus leaving the bottom 16bits unchanged | ||
531 | */ | ||
532 | break; | ||
533 | |||
534 | case R_MIPS_64: | ||
535 | case R_MIPS_32: | ||
536 | case R_MIPS_26: | ||
537 | case R_MIPS_HI16: | ||
538 | add_reloc(&relocs, rel->r_offset, r_type); | ||
539 | break; | ||
540 | |||
541 | default: | ||
542 | die("Unsupported relocation type: %s (%d)\n", | ||
543 | rel_type(r_type), r_type); | ||
544 | break; | ||
545 | } | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static int write_reloc_as_bin(uint32_t v, FILE *f) | ||
551 | { | ||
552 | unsigned char buf[4]; | ||
553 | |||
554 | v = cpu_to_elf32(v); | ||
555 | |||
556 | memcpy(buf, &v, sizeof(uint32_t)); | ||
557 | return fwrite(buf, 1, 4, f); | ||
558 | } | ||
559 | |||
560 | static int write_reloc_as_text(uint32_t v, FILE *f) | ||
561 | { | ||
562 | int res; | ||
563 | |||
564 | res = fprintf(f, "\t.long 0x%08"PRIx32"\n", v); | ||
565 | if (res < 0) | ||
566 | return res; | ||
567 | else | ||
568 | return sizeof(uint32_t); | ||
569 | } | ||
570 | |||
571 | static void emit_relocs(int as_text, int as_bin, FILE *outf) | ||
572 | { | ||
573 | int i; | ||
574 | int (*write_reloc)(uint32_t, FILE *) = write_reloc_as_bin; | ||
575 | int size = 0; | ||
576 | int size_reserved; | ||
577 | struct section *sec_reloc; | ||
578 | |||
579 | sec_reloc = sec_lookup(".data.reloc"); | ||
580 | if (!sec_reloc) | ||
581 | die("Could not find relocation section\n"); | ||
582 | |||
583 | size_reserved = sec_reloc->shdr.sh_size; | ||
584 | |||
585 | /* Collect up the relocations */ | ||
586 | walk_relocs(do_reloc); | ||
587 | |||
588 | /* Print the relocations */ | ||
589 | if (as_text) { | ||
590 | /* Print the relocations in a form suitable that | ||
591 | * gas will like. | ||
592 | */ | ||
593 | printf(".section \".data.reloc\",\"a\"\n"); | ||
594 | printf(".balign 4\n"); | ||
595 | /* Output text to stdout */ | ||
596 | write_reloc = write_reloc_as_text; | ||
597 | outf = stdout; | ||
598 | } else if (as_bin) { | ||
599 | /* Output raw binary to stdout */ | ||
600 | outf = stdout; | ||
601 | } else { | ||
602 | /* Seek to offset of the relocation section. | ||
603 | * Each relocation is then written into the | ||
604 | * vmlinux kernel image. | ||
605 | */ | ||
606 | if (fseek(outf, sec_reloc->shdr.sh_offset, SEEK_SET) < 0) { | ||
607 | die("Seek to %d failed: %s\n", | ||
608 | sec_reloc->shdr.sh_offset, strerror(errno)); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | for (i = 0; i < relocs.count; i++) | ||
613 | size += write_reloc(relocs.offset[i], outf); | ||
614 | |||
615 | /* Print a stop, but only if we've actually written some relocs */ | ||
616 | if (size) | ||
617 | size += write_reloc(0, outf); | ||
618 | |||
619 | if (size > size_reserved) | ||
620 | /* Die, but suggest a value for CONFIG_RELOCATION_TABLE_SIZE | ||
621 | * which will fix this problem and allow a bit of headroom | ||
622 | * if more kernel features are enabled | ||
623 | */ | ||
624 | die("Relocations overflow available space!\n" \ | ||
625 | "Please adjust CONFIG_RELOCATION_TABLE_SIZE " \ | ||
626 | "to at least 0x%08x\n", (size + 0x1000) & ~0xFFF); | ||
627 | } | ||
628 | |||
629 | /* | ||
630 | * As an aid to debugging problems with different linkers | ||
631 | * print summary information about the relocs. | ||
632 | * Since different linkers tend to emit the sections in | ||
633 | * different orders we use the section names in the output. | ||
634 | */ | ||
635 | static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, | ||
636 | const char *symname) | ||
637 | { | ||
638 | printf("%16s 0x%08x %16s %40s %16s\n", | ||
639 | sec_name(sec->shdr.sh_info), | ||
640 | (unsigned int)rel->r_offset, | ||
641 | rel_type(ELF_R_TYPE(rel->r_info)), | ||
642 | symname, | ||
643 | sec_name(sym->st_shndx)); | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | static void print_reloc_info(void) | ||
648 | { | ||
649 | printf("%16s %10s %16s %40s %16s\n", | ||
650 | "reloc section", | ||
651 | "offset", | ||
652 | "reloc type", | ||
653 | "symbol", | ||
654 | "symbol section"); | ||
655 | walk_relocs(do_reloc_info); | ||
656 | } | ||
657 | |||
658 | #if ELF_BITS == 64 | ||
659 | # define process process_64 | ||
660 | #else | ||
661 | # define process process_32 | ||
662 | #endif | ||
663 | |||
664 | void process(FILE *fp, int as_text, int as_bin, | ||
665 | int show_reloc_info, int keep_relocs) | ||
666 | { | ||
667 | regex_init(); | ||
668 | read_ehdr(fp); | ||
669 | read_shdrs(fp); | ||
670 | read_strtabs(fp); | ||
671 | read_symtabs(fp); | ||
672 | read_relocs(fp); | ||
673 | if (show_reloc_info) { | ||
674 | print_reloc_info(); | ||
675 | return; | ||
676 | } | ||
677 | emit_relocs(as_text, as_bin, fp); | ||
678 | if (!keep_relocs) | ||
679 | remove_relocs(fp); | ||
680 | } | ||
diff --git a/arch/mips/boot/tools/relocs.h b/arch/mips/boot/tools/relocs.h new file mode 100644 index 000000000000..3cf676f49e18 --- /dev/null +++ b/arch/mips/boot/tools/relocs.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef RELOCS_H | ||
2 | #define RELOCS_H | ||
3 | |||
4 | #include <stdio.h> | ||
5 | #include <stdarg.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <stdint.h> | ||
8 | #include <inttypes.h> | ||
9 | #include <string.h> | ||
10 | #include <errno.h> | ||
11 | #include <unistd.h> | ||
12 | #include <elf.h> | ||
13 | #include <byteswap.h> | ||
14 | #define USE_BSD | ||
15 | #include <endian.h> | ||
16 | #include <regex.h> | ||
17 | |||
18 | void die(char *fmt, ...); | ||
19 | |||
20 | /* | ||
21 | * Introduced for MIPSr6 | ||
22 | */ | ||
23 | #ifndef R_MIPS_PC21_S2 | ||
24 | #define R_MIPS_PC21_S2 60 | ||
25 | #endif | ||
26 | |||
27 | #ifndef R_MIPS_PC26_S2 | ||
28 | #define R_MIPS_PC26_S2 61 | ||
29 | #endif | ||
30 | |||
31 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
32 | |||
33 | enum symtype { | ||
34 | S_ABS, | ||
35 | S_REL, | ||
36 | S_SEG, | ||
37 | S_LIN, | ||
38 | S_NSYMTYPES | ||
39 | }; | ||
40 | |||
41 | void process_32(FILE *fp, int as_text, int as_bin, | ||
42 | int show_reloc_info, int keep_relocs); | ||
43 | void process_64(FILE *fp, int as_text, int as_bin, | ||
44 | int show_reloc_info, int keep_relocs); | ||
45 | #endif /* RELOCS_H */ | ||
diff --git a/arch/mips/boot/tools/relocs_32.c b/arch/mips/boot/tools/relocs_32.c new file mode 100644 index 000000000000..915bdc07f5ed --- /dev/null +++ b/arch/mips/boot/tools/relocs_32.c | |||
@@ -0,0 +1,17 @@ | |||
1 | #include "relocs.h" | ||
2 | |||
3 | #define ELF_BITS 32 | ||
4 | |||
5 | #define ELF_MACHINE EM_MIPS | ||
6 | #define ELF_MACHINE_NAME "MIPS" | ||
7 | #define SHT_REL_TYPE SHT_REL | ||
8 | #define Elf_Rel ElfW(Rel) | ||
9 | |||
10 | #define ELF_CLASS ELFCLASS32 | ||
11 | #define ELF_R_SYM(val) ELF32_R_SYM(val) | ||
12 | #define ELF_R_TYPE(val) ELF32_R_TYPE(val) | ||
13 | #define ELF_ST_TYPE(o) ELF32_ST_TYPE(o) | ||
14 | #define ELF_ST_BIND(o) ELF32_ST_BIND(o) | ||
15 | #define ELF_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o) | ||
16 | |||
17 | #include "relocs.c" | ||
diff --git a/arch/mips/boot/tools/relocs_64.c b/arch/mips/boot/tools/relocs_64.c new file mode 100644 index 000000000000..b671b5e2dcd8 --- /dev/null +++ b/arch/mips/boot/tools/relocs_64.c | |||
@@ -0,0 +1,27 @@ | |||
1 | #include "relocs.h" | ||
2 | |||
3 | #define ELF_BITS 64 | ||
4 | |||
5 | #define ELF_MACHINE EM_MIPS | ||
6 | #define ELF_MACHINE_NAME "MIPS64" | ||
7 | #define SHT_REL_TYPE SHT_RELA | ||
8 | #define Elf_Rel Elf64_Rela | ||
9 | |||
10 | typedef uint8_t Elf64_Byte; | ||
11 | |||
12 | typedef struct { | ||
13 | Elf64_Word r_sym; /* Symbol index. */ | ||
14 | Elf64_Byte r_ssym; /* Special symbol. */ | ||
15 | Elf64_Byte r_type3; /* Third relocation. */ | ||
16 | Elf64_Byte r_type2; /* Second relocation. */ | ||
17 | Elf64_Byte r_type; /* First relocation. */ | ||
18 | } Elf64_Mips_Rela; | ||
19 | |||
20 | #define ELF_CLASS ELFCLASS64 | ||
21 | #define ELF_R_SYM(val) (((Elf64_Mips_Rela *)(&val))->r_sym) | ||
22 | #define ELF_R_TYPE(val) (((Elf64_Mips_Rela *)(&val))->r_type) | ||
23 | #define ELF_ST_TYPE(o) ELF64_ST_TYPE(o) | ||
24 | #define ELF_ST_BIND(o) ELF64_ST_BIND(o) | ||
25 | #define ELF_ST_VISIBILITY(o) ELF64_ST_VISIBILITY(o) | ||
26 | |||
27 | #include "relocs.c" | ||
diff --git a/arch/mips/boot/tools/relocs_main.c b/arch/mips/boot/tools/relocs_main.c new file mode 100644 index 000000000000..d8fe2343b8d0 --- /dev/null +++ b/arch/mips/boot/tools/relocs_main.c | |||
@@ -0,0 +1,84 @@ | |||
1 | |||
2 | #include <stdio.h> | ||
3 | #include <stdint.h> | ||
4 | #include <stdarg.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <string.h> | ||
7 | #include <errno.h> | ||
8 | #include <endian.h> | ||
9 | #include <elf.h> | ||
10 | |||
11 | #include "relocs.h" | ||
12 | |||
13 | void die(char *fmt, ...) | ||
14 | { | ||
15 | va_list ap; | ||
16 | |||
17 | va_start(ap, fmt); | ||
18 | vfprintf(stderr, fmt, ap); | ||
19 | va_end(ap); | ||
20 | exit(1); | ||
21 | } | ||
22 | |||
23 | static void usage(void) | ||
24 | { | ||
25 | die("relocs [--reloc-info|--text|--bin|--keep] vmlinux\n"); | ||
26 | } | ||
27 | |||
28 | int main(int argc, char **argv) | ||
29 | { | ||
30 | int show_reloc_info, as_text, as_bin, keep_relocs; | ||
31 | const char *fname; | ||
32 | FILE *fp; | ||
33 | int i; | ||
34 | unsigned char e_ident[EI_NIDENT]; | ||
35 | |||
36 | show_reloc_info = 0; | ||
37 | as_text = 0; | ||
38 | as_bin = 0; | ||
39 | keep_relocs = 0; | ||
40 | fname = NULL; | ||
41 | for (i = 1; i < argc; i++) { | ||
42 | char *arg = argv[i]; | ||
43 | |||
44 | if (*arg == '-') { | ||
45 | if (strcmp(arg, "--reloc-info") == 0) { | ||
46 | show_reloc_info = 1; | ||
47 | continue; | ||
48 | } | ||
49 | if (strcmp(arg, "--text") == 0) { | ||
50 | as_text = 1; | ||
51 | continue; | ||
52 | } | ||
53 | if (strcmp(arg, "--bin") == 0) { | ||
54 | as_bin = 1; | ||
55 | continue; | ||
56 | } | ||
57 | if (strcmp(arg, "--keep") == 0) { | ||
58 | keep_relocs = 1; | ||
59 | continue; | ||
60 | } | ||
61 | } else if (!fname) { | ||
62 | fname = arg; | ||
63 | continue; | ||
64 | } | ||
65 | usage(); | ||
66 | } | ||
67 | if (!fname) | ||
68 | usage(); | ||
69 | |||
70 | fp = fopen(fname, "r+"); | ||
71 | if (!fp) | ||
72 | die("Cannot open %s: %s\n", fname, strerror(errno)); | ||
73 | |||
74 | if (fread(&e_ident, 1, EI_NIDENT, fp) != EI_NIDENT) | ||
75 | die("Cannot read %s: %s", fname, strerror(errno)); | ||
76 | |||
77 | rewind(fp); | ||
78 | if (e_ident[EI_CLASS] == ELFCLASS64) | ||
79 | process_64(fp, as_text, as_bin, show_reloc_info, keep_relocs); | ||
80 | else | ||
81 | process_32(fp, as_text, as_bin, show_reloc_info, keep_relocs); | ||
82 | fclose(fp); | ||
83 | return 0; | ||
84 | } | ||
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c index 1882e6475dd0..23c2344a3552 100644 --- a/arch/mips/cavium-octeon/csrc-octeon.c +++ b/arch/mips/cavium-octeon/csrc-octeon.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/octeon/cvmx-ipd-defs.h> | 19 | #include <asm/octeon/cvmx-ipd-defs.h> |
20 | #include <asm/octeon/cvmx-mio-defs.h> | 20 | #include <asm/octeon/cvmx-mio-defs.h> |
21 | #include <asm/octeon/cvmx-rst-defs.h> | 21 | #include <asm/octeon/cvmx-rst-defs.h> |
22 | #include <asm/octeon/cvmx-fpa-defs.h> | ||
22 | 23 | ||
23 | static u64 f; | 24 | static u64 f; |
24 | static u64 rdiv; | 25 | static u64 rdiv; |
@@ -65,9 +66,13 @@ void __init octeon_setup_delays(void) | |||
65 | */ | 66 | */ |
66 | void octeon_init_cvmcount(void) | 67 | void octeon_init_cvmcount(void) |
67 | { | 68 | { |
69 | u64 clk_reg; | ||
68 | unsigned long flags; | 70 | unsigned long flags; |
69 | unsigned loops = 2; | 71 | unsigned loops = 2; |
70 | 72 | ||
73 | clk_reg = octeon_has_feature(OCTEON_FEATURE_FPA3) ? | ||
74 | CVMX_FPA_CLK_COUNT : CVMX_IPD_CLK_COUNT; | ||
75 | |||
71 | /* Clobber loops so GCC will not unroll the following while loop. */ | 76 | /* Clobber loops so GCC will not unroll the following while loop. */ |
72 | asm("" : "+r" (loops)); | 77 | asm("" : "+r" (loops)); |
73 | 78 | ||
@@ -77,18 +82,18 @@ void octeon_init_cvmcount(void) | |||
77 | * which should give more deterministic timing. | 82 | * which should give more deterministic timing. |
78 | */ | 83 | */ |
79 | while (loops--) { | 84 | while (loops--) { |
80 | u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT); | 85 | u64 clk_count = cvmx_read_csr(clk_reg); |
81 | if (rdiv != 0) { | 86 | if (rdiv != 0) { |
82 | ipd_clk_count *= rdiv; | 87 | clk_count *= rdiv; |
83 | if (f != 0) { | 88 | if (f != 0) { |
84 | asm("dmultu\t%[cnt],%[f]\n\t" | 89 | asm("dmultu\t%[cnt],%[f]\n\t" |
85 | "mfhi\t%[cnt]" | 90 | "mfhi\t%[cnt]" |
86 | : [cnt] "+r" (ipd_clk_count) | 91 | : [cnt] "+r" (clk_count) |
87 | : [f] "r" (f) | 92 | : [f] "r" (f) |
88 | : "hi", "lo"); | 93 | : "hi", "lo"); |
89 | } | 94 | } |
90 | } | 95 | } |
91 | write_c0_cvmcount(ipd_clk_count); | 96 | write_c0_cvmcount(clk_count); |
92 | } | 97 | } |
93 | local_irq_restore(flags); | 98 | local_irq_restore(flags); |
94 | } | 99 | } |
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c index 376701f41cc2..ff26d0217b87 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c | |||
@@ -87,6 +87,8 @@ int cvmx_helper_get_number_of_interfaces(void) | |||
87 | return 9; | 87 | return 9; |
88 | if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) | 88 | if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) |
89 | return 4; | 89 | return 4; |
90 | if (OCTEON_IS_MODEL(OCTEON_CN7XXX)) | ||
91 | return 5; | ||
90 | else | 92 | else |
91 | return 3; | 93 | return 3; |
92 | } | 94 | } |
@@ -260,6 +262,41 @@ static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface) | |||
260 | } | 262 | } |
261 | 263 | ||
262 | /** | 264 | /** |
265 | * @INTERNAL | ||
266 | * Return interface mode for CN7XXX. | ||
267 | */ | ||
268 | static cvmx_helper_interface_mode_t __cvmx_get_mode_cn7xxx(int interface) | ||
269 | { | ||
270 | union cvmx_gmxx_inf_mode mode; | ||
271 | |||
272 | mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); | ||
273 | |||
274 | switch (interface) { | ||
275 | case 0: | ||
276 | case 1: | ||
277 | switch (mode.cn68xx.mode) { | ||
278 | case 0: | ||
279 | return CVMX_HELPER_INTERFACE_MODE_DISABLED; | ||
280 | case 1: | ||
281 | case 2: | ||
282 | return CVMX_HELPER_INTERFACE_MODE_SGMII; | ||
283 | case 3: | ||
284 | return CVMX_HELPER_INTERFACE_MODE_XAUI; | ||
285 | default: | ||
286 | return CVMX_HELPER_INTERFACE_MODE_SGMII; | ||
287 | } | ||
288 | case 2: | ||
289 | return CVMX_HELPER_INTERFACE_MODE_NPI; | ||
290 | case 3: | ||
291 | return CVMX_HELPER_INTERFACE_MODE_LOOP; | ||
292 | case 4: | ||
293 | return CVMX_HELPER_INTERFACE_MODE_RGMII; | ||
294 | default: | ||
295 | return CVMX_HELPER_INTERFACE_MODE_DISABLED; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | /** | ||
263 | * Get the operating mode of an interface. Depending on the Octeon | 300 | * Get the operating mode of an interface. Depending on the Octeon |
264 | * chip and configuration, this function returns an enumeration | 301 | * chip and configuration, this function returns an enumeration |
265 | * of the type of packet I/O supported by an interface. | 302 | * of the type of packet I/O supported by an interface. |
@@ -278,6 +315,12 @@ cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface) | |||
278 | return CVMX_HELPER_INTERFACE_MODE_DISABLED; | 315 | return CVMX_HELPER_INTERFACE_MODE_DISABLED; |
279 | 316 | ||
280 | /* | 317 | /* |
318 | * OCTEON III models | ||
319 | */ | ||
320 | if (OCTEON_IS_MODEL(OCTEON_CN7XXX)) | ||
321 | return __cvmx_get_mode_cn7xxx(interface); | ||
322 | |||
323 | /* | ||
281 | * Octeon II models | 324 | * Octeon II models |
282 | */ | 325 | */ |
283 | if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX)) | 326 | if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX)) |
diff --git a/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c index 3d17fac29359..cc1b1d2a6fa1 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c +++ b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c | |||
@@ -32,86 +32,22 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | 33 | ||
34 | #include <asm/octeon/cvmx.h> | 34 | #include <asm/octeon/cvmx.h> |
35 | #include <asm/octeon/cvmx-spinlock.h> | ||
36 | #include <asm/octeon/cvmx-sysinfo.h> | 35 | #include <asm/octeon/cvmx-sysinfo.h> |
37 | 36 | ||
38 | /** | 37 | /* |
39 | * This structure defines the private state maintained by sysinfo module. | 38 | * This structure defines the private state maintained by sysinfo module. |
40 | * | ||
41 | */ | 39 | */ |
42 | static struct { | 40 | static struct cvmx_sysinfo sysinfo; /* system information */ |
43 | struct cvmx_sysinfo sysinfo; /* system information */ | ||
44 | cvmx_spinlock_t lock; /* mutex spinlock */ | ||
45 | |||
46 | } state = { | ||
47 | .lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER | ||
48 | }; | ||
49 | |||
50 | 41 | ||
51 | /* | 42 | /* |
52 | * Global variables that define the min/max of the memory region set | 43 | * Returns the application information as obtained |
53 | * up for 32 bit userspace access. | ||
54 | */ | ||
55 | uint64_t linux_mem32_min; | ||
56 | uint64_t linux_mem32_max; | ||
57 | uint64_t linux_mem32_wired; | ||
58 | uint64_t linux_mem32_offset; | ||
59 | |||
60 | /** | ||
61 | * This function returns the application information as obtained | ||
62 | * by the bootloader. This provides the core mask of the cores | 44 | * by the bootloader. This provides the core mask of the cores |
63 | * running the same application image, as well as the physical | 45 | * running the same application image, as well as the physical |
64 | * memory regions available to the core. | 46 | * memory regions available to the core. |
65 | * | ||
66 | * Returns Pointer to the boot information structure | ||
67 | * | ||
68 | */ | 47 | */ |
69 | struct cvmx_sysinfo *cvmx_sysinfo_get(void) | 48 | struct cvmx_sysinfo *cvmx_sysinfo_get(void) |
70 | { | 49 | { |
71 | return &(state.sysinfo); | 50 | return &sysinfo; |
72 | } | 51 | } |
73 | EXPORT_SYMBOL(cvmx_sysinfo_get); | 52 | EXPORT_SYMBOL(cvmx_sysinfo_get); |
74 | 53 | ||
75 | /** | ||
76 | * This function is used in non-simple executive environments (such as | ||
77 | * Linux kernel, u-boot, etc.) to configure the minimal fields that | ||
78 | * are required to use simple executive files directly. | ||
79 | * | ||
80 | * Locking (if required) must be handled outside of this | ||
81 | * function | ||
82 | * | ||
83 | * @phy_mem_desc_ptr: | ||
84 | * Pointer to global physical memory descriptor | ||
85 | * (bootmem descriptor) @board_type: Octeon board | ||
86 | * type enumeration | ||
87 | * | ||
88 | * @board_rev_major: | ||
89 | * Board major revision | ||
90 | * @board_rev_minor: | ||
91 | * Board minor revision | ||
92 | * @cpu_clock_hz: | ||
93 | * CPU clock freqency in hertz | ||
94 | * | ||
95 | * Returns 0: Failure | ||
96 | * 1: success | ||
97 | */ | ||
98 | int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr, | ||
99 | uint16_t board_type, | ||
100 | uint8_t board_rev_major, | ||
101 | uint8_t board_rev_minor, | ||
102 | uint32_t cpu_clock_hz) | ||
103 | { | ||
104 | |||
105 | /* The sysinfo structure was already initialized */ | ||
106 | if (state.sysinfo.board_type) | ||
107 | return 0; | ||
108 | |||
109 | memset(&(state.sysinfo), 0x0, sizeof(state.sysinfo)); | ||
110 | state.sysinfo.phy_mem_desc_ptr = phy_mem_desc_ptr; | ||
111 | state.sysinfo.board_type = board_type; | ||
112 | state.sysinfo.board_rev_major = board_rev_major; | ||
113 | state.sysinfo.board_rev_minor = board_rev_minor; | ||
114 | state.sysinfo.cpu_clock_hz = cpu_clock_hz; | ||
115 | |||
116 | return 1; | ||
117 | } | ||
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index b2104bd9ab3b..d08a2bce653c 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c | |||
@@ -71,11 +71,11 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, | |||
71 | uint32_t fuse_data = 0; | 71 | uint32_t fuse_data = 0; |
72 | 72 | ||
73 | fus3.u64 = 0; | 73 | fus3.u64 = 0; |
74 | if (!OCTEON_IS_MODEL(OCTEON_CN6XXX)) | 74 | if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX)) |
75 | fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3); | 75 | fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3); |
76 | fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); | 76 | fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); |
77 | fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3); | 77 | fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3); |
78 | num_cores = cvmx_pop(cvmx_read_csr(CVMX_CIU_FUSE)); | 78 | num_cores = cvmx_octeon_num_cores(); |
79 | 79 | ||
80 | /* Make sure the non existent devices look disabled */ | 80 | /* Make sure the non existent devices look disabled */ |
81 | switch ((chip_id >> 8) & 0xff) { | 81 | switch ((chip_id >> 8) & 0xff) { |
@@ -121,6 +121,15 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, | |||
121 | * later. | 121 | * later. |
122 | */ | 122 | */ |
123 | switch (num_cores) { | 123 | switch (num_cores) { |
124 | case 48: | ||
125 | core_model = "90"; | ||
126 | break; | ||
127 | case 44: | ||
128 | core_model = "88"; | ||
129 | break; | ||
130 | case 40: | ||
131 | core_model = "85"; | ||
132 | break; | ||
124 | case 32: | 133 | case 32: |
125 | core_model = "80"; | 134 | core_model = "80"; |
126 | break; | 135 | break; |
@@ -297,7 +306,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, | |||
297 | if (fus_dat3.s.nozip) | 306 | if (fus_dat3.s.nozip) |
298 | suffix = "SCP"; | 307 | suffix = "SCP"; |
299 | 308 | ||
300 | if (fus_dat3.s.bar2_en) | 309 | if (fus_dat3.cn56xx.bar2_en) |
301 | suffix = "NSPB2"; | 310 | suffix = "NSPB2"; |
302 | } | 311 | } |
303 | if (fus3.cn56xx.crip_1024k) | 312 | if (fus3.cn56xx.crip_1024k) |
@@ -369,6 +378,73 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, | |||
369 | else | 378 | else |
370 | suffix = "AAP"; | 379 | suffix = "AAP"; |
371 | break; | 380 | break; |
381 | case 0x94: /* CNF71XX */ | ||
382 | family = "F71"; | ||
383 | if (fus_dat3.cnf71xx.nozip) | ||
384 | suffix = "SCP"; | ||
385 | else | ||
386 | suffix = "AAP"; | ||
387 | break; | ||
388 | case 0x95: /* CN78XX */ | ||
389 | if (num_cores == 6) /* Other core counts match generic */ | ||
390 | core_model = "35"; | ||
391 | if (OCTEON_IS_MODEL(OCTEON_CN76XX)) | ||
392 | family = "76"; | ||
393 | else | ||
394 | family = "78"; | ||
395 | if (fus_dat3.cn78xx.l2c_crip == 2) | ||
396 | family = "77"; | ||
397 | if (fus_dat3.cn78xx.nozip | ||
398 | && fus_dat3.cn78xx.nodfa_dte | ||
399 | && fus_dat3.cn78xx.nohna_dte) { | ||
400 | if (fus_dat3.cn78xx.nozip && | ||
401 | !fus_dat2.cn78xx.raid_en && | ||
402 | fus_dat3.cn78xx.nohna_dte) { | ||
403 | suffix = "CP"; | ||
404 | } else { | ||
405 | suffix = "SCP"; | ||
406 | } | ||
407 | } else if (fus_dat2.cn78xx.raid_en == 0) | ||
408 | suffix = "HCP"; | ||
409 | else | ||
410 | suffix = "AAP"; | ||
411 | break; | ||
412 | case 0x96: /* CN70XX */ | ||
413 | family = "70"; | ||
414 | if (cvmx_read_csr(CVMX_MIO_FUS_PDF) & (0x1ULL << 32)) | ||
415 | family = "71"; | ||
416 | if (fus_dat2.cn70xx.nocrypto) | ||
417 | suffix = "CP"; | ||
418 | else if (fus_dat3.cn70xx.nodfa_dte) | ||
419 | suffix = "SCP"; | ||
420 | else | ||
421 | suffix = "AAP"; | ||
422 | break; | ||
423 | case 0x97: /* CN73XX */ | ||
424 | if (num_cores == 6) /* Other core counts match generic */ | ||
425 | core_model = "35"; | ||
426 | family = "73"; | ||
427 | if (fus_dat3.cn73xx.l2c_crip == 2) | ||
428 | family = "72"; | ||
429 | if (fus_dat3.cn73xx.nozip | ||
430 | && fus_dat3.cn73xx.nodfa_dte | ||
431 | && fus_dat3.cn73xx.nohna_dte) { | ||
432 | if (!fus_dat2.cn73xx.raid_en) | ||
433 | suffix = "CP"; | ||
434 | else | ||
435 | suffix = "SCP"; | ||
436 | } else | ||
437 | suffix = "AAP"; | ||
438 | break; | ||
439 | case 0x98: /* CN75XX */ | ||
440 | family = "F75"; | ||
441 | if (fus_dat3.cn78xx.nozip | ||
442 | && fus_dat3.cn78xx.nodfa_dte | ||
443 | && fus_dat3.cn78xx.nohna_dte) | ||
444 | suffix = "SCP"; | ||
445 | else | ||
446 | suffix = "AAP"; | ||
447 | break; | ||
372 | default: | 448 | default: |
373 | family = "XX"; | 449 | family = "XX"; |
374 | core_model = "XX"; | 450 | core_model = "XX"; |
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 4f9eb0576884..368eb490354c 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c | |||
@@ -3,7 +3,7 @@ | |||
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) 2004-2014 Cavium, Inc. | 6 | * Copyright (C) 2004-2016 Cavium, Inc. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/of_address.h> | 9 | #include <linux/of_address.h> |
@@ -19,16 +19,53 @@ | |||
19 | 19 | ||
20 | #include <asm/octeon/octeon.h> | 20 | #include <asm/octeon/octeon.h> |
21 | #include <asm/octeon/cvmx-ciu2-defs.h> | 21 | #include <asm/octeon/cvmx-ciu2-defs.h> |
22 | #include <asm/octeon/cvmx-ciu3-defs.h> | ||
22 | 23 | ||
23 | static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror); | 24 | static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror); |
24 | static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror); | 25 | static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror); |
25 | static DEFINE_PER_CPU(raw_spinlock_t, octeon_irq_ciu_spinlock); | 26 | static DEFINE_PER_CPU(raw_spinlock_t, octeon_irq_ciu_spinlock); |
27 | static DEFINE_PER_CPU(unsigned int, octeon_irq_ciu3_idt_ip2); | ||
28 | |||
29 | static DEFINE_PER_CPU(unsigned int, octeon_irq_ciu3_idt_ip3); | ||
30 | static DEFINE_PER_CPU(struct octeon_ciu3_info *, octeon_ciu3_info); | ||
31 | #define CIU3_MBOX_PER_CORE 10 | ||
32 | |||
33 | /* | ||
34 | * The 8 most significant bits of the intsn identify the interrupt major block. | ||
35 | * Each major block might use its own interrupt domain. Thus 256 domains are | ||
36 | * needed. | ||
37 | */ | ||
38 | #define MAX_CIU3_DOMAINS 256 | ||
39 | |||
40 | typedef irq_hw_number_t (*octeon_ciu3_intsn2hw_t)(struct irq_domain *, unsigned int); | ||
41 | |||
42 | /* Information for each ciu3 in the system */ | ||
43 | struct octeon_ciu3_info { | ||
44 | u64 ciu3_addr; | ||
45 | int node; | ||
46 | struct irq_domain *domain[MAX_CIU3_DOMAINS]; | ||
47 | octeon_ciu3_intsn2hw_t intsn2hw[MAX_CIU3_DOMAINS]; | ||
48 | }; | ||
49 | |||
50 | /* Each ciu3 in the system uses its own data (one ciu3 per node) */ | ||
51 | static struct octeon_ciu3_info *octeon_ciu3_info_per_node[4]; | ||
26 | 52 | ||
27 | struct octeon_irq_ciu_domain_data { | 53 | struct octeon_irq_ciu_domain_data { |
28 | int num_sum; /* number of sum registers (2 or 3). */ | 54 | int num_sum; /* number of sum registers (2 or 3). */ |
29 | }; | 55 | }; |
30 | 56 | ||
31 | static __read_mostly u8 octeon_irq_ciu_to_irq[8][64]; | 57 | /* Register offsets from ciu3_addr */ |
58 | #define CIU3_CONST 0x220 | ||
59 | #define CIU3_IDT_CTL(_idt) ((_idt) * 8 + 0x110000) | ||
60 | #define CIU3_IDT_PP(_idt, _idx) ((_idt) * 32 + (_idx) * 8 + 0x120000) | ||
61 | #define CIU3_IDT_IO(_idt) ((_idt) * 8 + 0x130000) | ||
62 | #define CIU3_DEST_PP_INT(_pp_ip) ((_pp_ip) * 8 + 0x200000) | ||
63 | #define CIU3_DEST_IO_INT(_io) ((_io) * 8 + 0x210000) | ||
64 | #define CIU3_ISC_CTL(_intsn) ((_intsn) * 8 + 0x80000000) | ||
65 | #define CIU3_ISC_W1C(_intsn) ((_intsn) * 8 + 0x90000000) | ||
66 | #define CIU3_ISC_W1S(_intsn) ((_intsn) * 8 + 0xa0000000) | ||
67 | |||
68 | static __read_mostly int octeon_irq_ciu_to_irq[8][64]; | ||
32 | 69 | ||
33 | struct octeon_ciu_chip_data { | 70 | struct octeon_ciu_chip_data { |
34 | union { | 71 | union { |
@@ -39,10 +76,11 @@ struct octeon_ciu_chip_data { | |||
39 | struct { /* only used for ciu/ciu2 */ | 76 | struct { /* only used for ciu/ciu2 */ |
40 | u8 line; | 77 | u8 line; |
41 | u8 bit; | 78 | u8 bit; |
42 | u8 gpio_line; | ||
43 | }; | 79 | }; |
44 | }; | 80 | }; |
81 | int gpio_line; | ||
45 | int current_cpu; /* Next CPU expected to take this irq */ | 82 | int current_cpu; /* Next CPU expected to take this irq */ |
83 | int ciu_node; /* NUMA node number of the CIU */ | ||
46 | }; | 84 | }; |
47 | 85 | ||
48 | struct octeon_core_chip_data { | 86 | struct octeon_core_chip_data { |
@@ -626,6 +664,18 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data) | |||
626 | } | 664 | } |
627 | } | 665 | } |
628 | 666 | ||
667 | static int octeon_irq_ciu_set_type(struct irq_data *data, unsigned int t) | ||
668 | { | ||
669 | irqd_set_trigger_type(data, t); | ||
670 | |||
671 | if (t & IRQ_TYPE_EDGE_BOTH) | ||
672 | irq_set_handler_locked(data, handle_edge_irq); | ||
673 | else | ||
674 | irq_set_handler_locked(data, handle_level_irq); | ||
675 | |||
676 | return IRQ_SET_MASK_OK; | ||
677 | } | ||
678 | |||
629 | static void octeon_irq_gpio_setup(struct irq_data *data) | 679 | static void octeon_irq_gpio_setup(struct irq_data *data) |
630 | { | 680 | { |
631 | union cvmx_gpio_bit_cfgx cfg; | 681 | union cvmx_gpio_bit_cfgx cfg; |
@@ -663,7 +713,7 @@ static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t) | |||
663 | irqd_set_trigger_type(data, t); | 713 | irqd_set_trigger_type(data, t); |
664 | octeon_irq_gpio_setup(data); | 714 | octeon_irq_gpio_setup(data); |
665 | 715 | ||
666 | if (irqd_get_trigger_type(data) & IRQ_TYPE_EDGE_BOTH) | 716 | if (t & IRQ_TYPE_EDGE_BOTH) |
667 | irq_set_handler_locked(data, handle_edge_irq); | 717 | irq_set_handler_locked(data, handle_edge_irq); |
668 | else | 718 | else |
669 | irq_set_handler_locked(data, handle_level_irq); | 719 | irq_set_handler_locked(data, handle_level_irq); |
@@ -863,6 +913,16 @@ static int octeon_irq_ciu_set_affinity_sum2(struct irq_data *data, | |||
863 | } | 913 | } |
864 | #endif | 914 | #endif |
865 | 915 | ||
916 | static unsigned int edge_startup(struct irq_data *data) | ||
917 | { | ||
918 | /* ack any pending edge-irq at startup, so there is | ||
919 | * an _edge_ to fire on when the event reappears. | ||
920 | */ | ||
921 | data->chip->irq_ack(data); | ||
922 | data->chip->irq_enable(data); | ||
923 | return 0; | ||
924 | } | ||
925 | |||
866 | /* | 926 | /* |
867 | * Newer octeon chips have support for lockless CIU operation. | 927 | * Newer octeon chips have support for lockless CIU operation. |
868 | */ | 928 | */ |
@@ -1158,16 +1218,6 @@ static struct irq_chip *octeon_irq_ciu_chip; | |||
1158 | static struct irq_chip *octeon_irq_ciu_chip_edge; | 1218 | static struct irq_chip *octeon_irq_ciu_chip_edge; |
1159 | static struct irq_chip *octeon_irq_gpio_chip; | 1219 | static struct irq_chip *octeon_irq_gpio_chip; |
1160 | 1220 | ||
1161 | static bool octeon_irq_virq_in_range(unsigned int virq) | ||
1162 | { | ||
1163 | /* We cannot let it overflow the mapping array. */ | ||
1164 | if (virq < (1ul << 8 * sizeof(octeon_irq_ciu_to_irq[0][0]))) | ||
1165 | return true; | ||
1166 | |||
1167 | WARN_ONCE(true, "virq out of range %u.\n", virq); | ||
1168 | return false; | ||
1169 | } | ||
1170 | |||
1171 | static int octeon_irq_ciu_map(struct irq_domain *d, | 1221 | static int octeon_irq_ciu_map(struct irq_domain *d, |
1172 | unsigned int virq, irq_hw_number_t hw) | 1222 | unsigned int virq, irq_hw_number_t hw) |
1173 | { | 1223 | { |
@@ -1176,13 +1226,6 @@ static int octeon_irq_ciu_map(struct irq_domain *d, | |||
1176 | unsigned int bit = hw & 63; | 1226 | unsigned int bit = hw & 63; |
1177 | struct octeon_irq_ciu_domain_data *dd = d->host_data; | 1227 | struct octeon_irq_ciu_domain_data *dd = d->host_data; |
1178 | 1228 | ||
1179 | if (!octeon_irq_virq_in_range(virq)) | ||
1180 | return -EINVAL; | ||
1181 | |||
1182 | /* Don't map irq if it is reserved for GPIO. */ | ||
1183 | if (line == 0 && bit >= 16 && bit <32) | ||
1184 | return 0; | ||
1185 | |||
1186 | if (line >= dd->num_sum || octeon_irq_ciu_to_irq[line][bit] != 0) | 1229 | if (line >= dd->num_sum || octeon_irq_ciu_to_irq[line][bit] != 0) |
1187 | return -EINVAL; | 1230 | return -EINVAL; |
1188 | 1231 | ||
@@ -1215,9 +1258,6 @@ static int octeon_irq_gpio_map(struct irq_domain *d, | |||
1215 | unsigned int line, bit; | 1258 | unsigned int line, bit; |
1216 | int r; | 1259 | int r; |
1217 | 1260 | ||
1218 | if (!octeon_irq_virq_in_range(virq)) | ||
1219 | return -EINVAL; | ||
1220 | |||
1221 | line = (hw + gpiod->base_hwirq) >> 6; | 1261 | line = (hw + gpiod->base_hwirq) >> 6; |
1222 | bit = (hw + gpiod->base_hwirq) & 63; | 1262 | bit = (hw + gpiod->base_hwirq) & 63; |
1223 | if (line > ARRAY_SIZE(octeon_irq_ciu_to_irq) || | 1263 | if (line > ARRAY_SIZE(octeon_irq_ciu_to_irq) || |
@@ -1899,9 +1939,6 @@ static int octeon_irq_ciu2_map(struct irq_domain *d, | |||
1899 | unsigned int line = hw >> 6; | 1939 | unsigned int line = hw >> 6; |
1900 | unsigned int bit = hw & 63; | 1940 | unsigned int bit = hw & 63; |
1901 | 1941 | ||
1902 | if (!octeon_irq_virq_in_range(virq)) | ||
1903 | return -EINVAL; | ||
1904 | |||
1905 | /* | 1942 | /* |
1906 | * Don't map irq if it is reserved for GPIO. | 1943 | * Don't map irq if it is reserved for GPIO. |
1907 | * (Line 7 are the GPIO lines.) | 1944 | * (Line 7 are the GPIO lines.) |
@@ -2294,10 +2331,598 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node, | |||
2294 | return 0; | 2331 | return 0; |
2295 | } | 2332 | } |
2296 | 2333 | ||
2334 | int octeon_irq_ciu3_xlat(struct irq_domain *d, | ||
2335 | struct device_node *node, | ||
2336 | const u32 *intspec, | ||
2337 | unsigned int intsize, | ||
2338 | unsigned long *out_hwirq, | ||
2339 | unsigned int *out_type) | ||
2340 | { | ||
2341 | struct octeon_ciu3_info *ciu3_info = d->host_data; | ||
2342 | unsigned int hwirq, type, intsn_major; | ||
2343 | union cvmx_ciu3_iscx_ctl isc; | ||
2344 | |||
2345 | if (intsize < 2) | ||
2346 | return -EINVAL; | ||
2347 | hwirq = intspec[0]; | ||
2348 | type = intspec[1]; | ||
2349 | |||
2350 | if (hwirq >= (1 << 20)) | ||
2351 | return -EINVAL; | ||
2352 | |||
2353 | intsn_major = hwirq >> 12; | ||
2354 | switch (intsn_major) { | ||
2355 | case 0x04: /* Software handled separately. */ | ||
2356 | return -EINVAL; | ||
2357 | default: | ||
2358 | break; | ||
2359 | } | ||
2360 | |||
2361 | isc.u64 = cvmx_read_csr(ciu3_info->ciu3_addr + CIU3_ISC_CTL(hwirq)); | ||
2362 | if (!isc.s.imp) | ||
2363 | return -EINVAL; | ||
2364 | |||
2365 | switch (type) { | ||
2366 | case 4: /* official value for level triggering. */ | ||
2367 | *out_type = IRQ_TYPE_LEVEL_HIGH; | ||
2368 | break; | ||
2369 | case 0: /* unofficial value, but we might as well let it work. */ | ||
2370 | case 1: /* official value for edge triggering. */ | ||
2371 | *out_type = IRQ_TYPE_EDGE_RISING; | ||
2372 | break; | ||
2373 | default: /* Nothing else is acceptable. */ | ||
2374 | return -EINVAL; | ||
2375 | } | ||
2376 | |||
2377 | *out_hwirq = hwirq; | ||
2378 | |||
2379 | return 0; | ||
2380 | } | ||
2381 | |||
2382 | void octeon_irq_ciu3_enable(struct irq_data *data) | ||
2383 | { | ||
2384 | int cpu; | ||
2385 | union cvmx_ciu3_iscx_ctl isc_ctl; | ||
2386 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2387 | u64 isc_ctl_addr; | ||
2388 | |||
2389 | struct octeon_ciu_chip_data *cd; | ||
2390 | |||
2391 | cpu = next_cpu_for_irq(data); | ||
2392 | |||
2393 | cd = irq_data_get_irq_chip_data(data); | ||
2394 | |||
2395 | isc_w1c.u64 = 0; | ||
2396 | isc_w1c.s.en = 1; | ||
2397 | cvmx_write_csr(cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn), isc_w1c.u64); | ||
2398 | |||
2399 | isc_ctl_addr = cd->ciu3_addr + CIU3_ISC_CTL(cd->intsn); | ||
2400 | isc_ctl.u64 = 0; | ||
2401 | isc_ctl.s.en = 1; | ||
2402 | isc_ctl.s.idt = per_cpu(octeon_irq_ciu3_idt_ip2, cpu); | ||
2403 | cvmx_write_csr(isc_ctl_addr, isc_ctl.u64); | ||
2404 | cvmx_read_csr(isc_ctl_addr); | ||
2405 | } | ||
2406 | |||
2407 | void octeon_irq_ciu3_disable(struct irq_data *data) | ||
2408 | { | ||
2409 | u64 isc_ctl_addr; | ||
2410 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2411 | |||
2412 | struct octeon_ciu_chip_data *cd; | ||
2413 | |||
2414 | cd = irq_data_get_irq_chip_data(data); | ||
2415 | |||
2416 | isc_w1c.u64 = 0; | ||
2417 | isc_w1c.s.en = 1; | ||
2418 | |||
2419 | isc_ctl_addr = cd->ciu3_addr + CIU3_ISC_CTL(cd->intsn); | ||
2420 | cvmx_write_csr(cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn), isc_w1c.u64); | ||
2421 | cvmx_write_csr(isc_ctl_addr, 0); | ||
2422 | cvmx_read_csr(isc_ctl_addr); | ||
2423 | } | ||
2424 | |||
2425 | void octeon_irq_ciu3_ack(struct irq_data *data) | ||
2426 | { | ||
2427 | u64 isc_w1c_addr; | ||
2428 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2429 | struct octeon_ciu_chip_data *cd; | ||
2430 | u32 trigger_type = irqd_get_trigger_type(data); | ||
2431 | |||
2432 | /* | ||
2433 | * We use a single irq_chip, so we have to do nothing to ack a | ||
2434 | * level interrupt. | ||
2435 | */ | ||
2436 | if (!(trigger_type & IRQ_TYPE_EDGE_BOTH)) | ||
2437 | return; | ||
2438 | |||
2439 | cd = irq_data_get_irq_chip_data(data); | ||
2440 | |||
2441 | isc_w1c.u64 = 0; | ||
2442 | isc_w1c.s.raw = 1; | ||
2443 | |||
2444 | isc_w1c_addr = cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn); | ||
2445 | cvmx_write_csr(isc_w1c_addr, isc_w1c.u64); | ||
2446 | cvmx_read_csr(isc_w1c_addr); | ||
2447 | } | ||
2448 | |||
2449 | void octeon_irq_ciu3_mask(struct irq_data *data) | ||
2450 | { | ||
2451 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2452 | u64 isc_w1c_addr; | ||
2453 | struct octeon_ciu_chip_data *cd; | ||
2454 | |||
2455 | cd = irq_data_get_irq_chip_data(data); | ||
2456 | |||
2457 | isc_w1c.u64 = 0; | ||
2458 | isc_w1c.s.en = 1; | ||
2459 | |||
2460 | isc_w1c_addr = cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn); | ||
2461 | cvmx_write_csr(isc_w1c_addr, isc_w1c.u64); | ||
2462 | cvmx_read_csr(isc_w1c_addr); | ||
2463 | } | ||
2464 | |||
2465 | void octeon_irq_ciu3_mask_ack(struct irq_data *data) | ||
2466 | { | ||
2467 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2468 | u64 isc_w1c_addr; | ||
2469 | struct octeon_ciu_chip_data *cd; | ||
2470 | u32 trigger_type = irqd_get_trigger_type(data); | ||
2471 | |||
2472 | cd = irq_data_get_irq_chip_data(data); | ||
2473 | |||
2474 | isc_w1c.u64 = 0; | ||
2475 | isc_w1c.s.en = 1; | ||
2476 | |||
2477 | /* | ||
2478 | * We use a single irq_chip, so only ack an edge (!level) | ||
2479 | * interrupt. | ||
2480 | */ | ||
2481 | if (trigger_type & IRQ_TYPE_EDGE_BOTH) | ||
2482 | isc_w1c.s.raw = 1; | ||
2483 | |||
2484 | isc_w1c_addr = cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn); | ||
2485 | cvmx_write_csr(isc_w1c_addr, isc_w1c.u64); | ||
2486 | cvmx_read_csr(isc_w1c_addr); | ||
2487 | } | ||
2488 | |||
2489 | #ifdef CONFIG_SMP | ||
2490 | int octeon_irq_ciu3_set_affinity(struct irq_data *data, | ||
2491 | const struct cpumask *dest, bool force) | ||
2492 | { | ||
2493 | union cvmx_ciu3_iscx_ctl isc_ctl; | ||
2494 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2495 | u64 isc_ctl_addr; | ||
2496 | int cpu; | ||
2497 | bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data); | ||
2498 | struct octeon_ciu_chip_data *cd = irq_data_get_irq_chip_data(data); | ||
2499 | |||
2500 | if (!cpumask_subset(dest, cpumask_of_node(cd->ciu_node))) | ||
2501 | return -EINVAL; | ||
2502 | |||
2503 | if (!enable_one) | ||
2504 | return IRQ_SET_MASK_OK; | ||
2505 | |||
2506 | cd = irq_data_get_irq_chip_data(data); | ||
2507 | cpu = cpumask_first(dest); | ||
2508 | if (cpu >= nr_cpu_ids) | ||
2509 | cpu = smp_processor_id(); | ||
2510 | cd->current_cpu = cpu; | ||
2511 | |||
2512 | isc_w1c.u64 = 0; | ||
2513 | isc_w1c.s.en = 1; | ||
2514 | cvmx_write_csr(cd->ciu3_addr + CIU3_ISC_W1C(cd->intsn), isc_w1c.u64); | ||
2515 | |||
2516 | isc_ctl_addr = cd->ciu3_addr + CIU3_ISC_CTL(cd->intsn); | ||
2517 | isc_ctl.u64 = 0; | ||
2518 | isc_ctl.s.en = 1; | ||
2519 | isc_ctl.s.idt = per_cpu(octeon_irq_ciu3_idt_ip2, cpu); | ||
2520 | cvmx_write_csr(isc_ctl_addr, isc_ctl.u64); | ||
2521 | cvmx_read_csr(isc_ctl_addr); | ||
2522 | |||
2523 | return IRQ_SET_MASK_OK; | ||
2524 | } | ||
2525 | #endif | ||
2526 | |||
2527 | static struct irq_chip octeon_irq_chip_ciu3 = { | ||
2528 | .name = "CIU3", | ||
2529 | .irq_startup = edge_startup, | ||
2530 | .irq_enable = octeon_irq_ciu3_enable, | ||
2531 | .irq_disable = octeon_irq_ciu3_disable, | ||
2532 | .irq_ack = octeon_irq_ciu3_ack, | ||
2533 | .irq_mask = octeon_irq_ciu3_mask, | ||
2534 | .irq_mask_ack = octeon_irq_ciu3_mask_ack, | ||
2535 | .irq_unmask = octeon_irq_ciu3_enable, | ||
2536 | .irq_set_type = octeon_irq_ciu_set_type, | ||
2537 | #ifdef CONFIG_SMP | ||
2538 | .irq_set_affinity = octeon_irq_ciu3_set_affinity, | ||
2539 | .irq_cpu_offline = octeon_irq_cpu_offline_ciu, | ||
2540 | #endif | ||
2541 | }; | ||
2542 | |||
2543 | int octeon_irq_ciu3_mapx(struct irq_domain *d, unsigned int virq, | ||
2544 | irq_hw_number_t hw, struct irq_chip *chip) | ||
2545 | { | ||
2546 | struct octeon_ciu3_info *ciu3_info = d->host_data; | ||
2547 | struct octeon_ciu_chip_data *cd = kzalloc_node(sizeof(*cd), GFP_KERNEL, | ||
2548 | ciu3_info->node); | ||
2549 | if (!cd) | ||
2550 | return -ENOMEM; | ||
2551 | cd->intsn = hw; | ||
2552 | cd->current_cpu = -1; | ||
2553 | cd->ciu3_addr = ciu3_info->ciu3_addr; | ||
2554 | cd->ciu_node = ciu3_info->node; | ||
2555 | irq_set_chip_and_handler(virq, chip, handle_edge_irq); | ||
2556 | irq_set_chip_data(virq, cd); | ||
2557 | |||
2558 | return 0; | ||
2559 | } | ||
2560 | |||
2561 | static int octeon_irq_ciu3_map(struct irq_domain *d, | ||
2562 | unsigned int virq, irq_hw_number_t hw) | ||
2563 | { | ||
2564 | return octeon_irq_ciu3_mapx(d, virq, hw, &octeon_irq_chip_ciu3); | ||
2565 | } | ||
2566 | |||
2567 | static struct irq_domain_ops octeon_dflt_domain_ciu3_ops = { | ||
2568 | .map = octeon_irq_ciu3_map, | ||
2569 | .unmap = octeon_irq_free_cd, | ||
2570 | .xlate = octeon_irq_ciu3_xlat, | ||
2571 | }; | ||
2572 | |||
2573 | static void octeon_irq_ciu3_ip2(void) | ||
2574 | { | ||
2575 | union cvmx_ciu3_destx_pp_int dest_pp_int; | ||
2576 | struct octeon_ciu3_info *ciu3_info; | ||
2577 | u64 ciu3_addr; | ||
2578 | |||
2579 | ciu3_info = __this_cpu_read(octeon_ciu3_info); | ||
2580 | ciu3_addr = ciu3_info->ciu3_addr; | ||
2581 | |||
2582 | dest_pp_int.u64 = cvmx_read_csr(ciu3_addr + CIU3_DEST_PP_INT(3 * cvmx_get_local_core_num())); | ||
2583 | |||
2584 | if (likely(dest_pp_int.s.intr)) { | ||
2585 | irq_hw_number_t intsn = dest_pp_int.s.intsn; | ||
2586 | irq_hw_number_t hw; | ||
2587 | struct irq_domain *domain; | ||
2588 | /* Get the domain to use from the major block */ | ||
2589 | int block = intsn >> 12; | ||
2590 | int ret; | ||
2591 | |||
2592 | domain = ciu3_info->domain[block]; | ||
2593 | if (ciu3_info->intsn2hw[block]) | ||
2594 | hw = ciu3_info->intsn2hw[block](domain, intsn); | ||
2595 | else | ||
2596 | hw = intsn; | ||
2597 | |||
2598 | ret = handle_domain_irq(domain, hw, NULL); | ||
2599 | if (ret < 0) { | ||
2600 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2601 | u64 isc_w1c_addr = ciu3_addr + CIU3_ISC_W1C(intsn); | ||
2602 | |||
2603 | isc_w1c.u64 = 0; | ||
2604 | isc_w1c.s.en = 1; | ||
2605 | cvmx_write_csr(isc_w1c_addr, isc_w1c.u64); | ||
2606 | cvmx_read_csr(isc_w1c_addr); | ||
2607 | spurious_interrupt(); | ||
2608 | } | ||
2609 | } else { | ||
2610 | spurious_interrupt(); | ||
2611 | } | ||
2612 | } | ||
2613 | |||
2614 | /* | ||
2615 | * 10 mbox per core starting from zero. | ||
2616 | * Base mbox is core * 10 | ||
2617 | */ | ||
2618 | static unsigned int octeon_irq_ciu3_base_mbox_intsn(int core) | ||
2619 | { | ||
2620 | /* SW (mbox) are 0x04 in bits 12..19 */ | ||
2621 | return 0x04000 + CIU3_MBOX_PER_CORE * core; | ||
2622 | } | ||
2623 | |||
2624 | static unsigned int octeon_irq_ciu3_mbox_intsn_for_core(int core, unsigned int mbox) | ||
2625 | { | ||
2626 | return octeon_irq_ciu3_base_mbox_intsn(core) + mbox; | ||
2627 | } | ||
2628 | |||
2629 | static unsigned int octeon_irq_ciu3_mbox_intsn_for_cpu(int cpu, unsigned int mbox) | ||
2630 | { | ||
2631 | int local_core = octeon_coreid_for_cpu(cpu) & 0x3f; | ||
2632 | |||
2633 | return octeon_irq_ciu3_mbox_intsn_for_core(local_core, mbox); | ||
2634 | } | ||
2635 | |||
2636 | static void octeon_irq_ciu3_mbox(void) | ||
2637 | { | ||
2638 | union cvmx_ciu3_destx_pp_int dest_pp_int; | ||
2639 | struct octeon_ciu3_info *ciu3_info; | ||
2640 | u64 ciu3_addr; | ||
2641 | int core = cvmx_get_local_core_num(); | ||
2642 | |||
2643 | ciu3_info = __this_cpu_read(octeon_ciu3_info); | ||
2644 | ciu3_addr = ciu3_info->ciu3_addr; | ||
2645 | |||
2646 | dest_pp_int.u64 = cvmx_read_csr(ciu3_addr + CIU3_DEST_PP_INT(1 + 3 * core)); | ||
2647 | |||
2648 | if (likely(dest_pp_int.s.intr)) { | ||
2649 | irq_hw_number_t intsn = dest_pp_int.s.intsn; | ||
2650 | int mbox = intsn - octeon_irq_ciu3_base_mbox_intsn(core); | ||
2651 | |||
2652 | if (likely(mbox >= 0 && mbox < CIU3_MBOX_PER_CORE)) { | ||
2653 | do_IRQ(mbox + OCTEON_IRQ_MBOX0); | ||
2654 | } else { | ||
2655 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2656 | u64 isc_w1c_addr = ciu3_addr + CIU3_ISC_W1C(intsn); | ||
2657 | |||
2658 | isc_w1c.u64 = 0; | ||
2659 | isc_w1c.s.en = 1; | ||
2660 | cvmx_write_csr(isc_w1c_addr, isc_w1c.u64); | ||
2661 | cvmx_read_csr(isc_w1c_addr); | ||
2662 | spurious_interrupt(); | ||
2663 | } | ||
2664 | } else { | ||
2665 | spurious_interrupt(); | ||
2666 | } | ||
2667 | } | ||
2668 | |||
2669 | void octeon_ciu3_mbox_send(int cpu, unsigned int mbox) | ||
2670 | { | ||
2671 | struct octeon_ciu3_info *ciu3_info; | ||
2672 | unsigned int intsn; | ||
2673 | union cvmx_ciu3_iscx_w1s isc_w1s; | ||
2674 | u64 isc_w1s_addr; | ||
2675 | |||
2676 | if (WARN_ON_ONCE(mbox >= CIU3_MBOX_PER_CORE)) | ||
2677 | return; | ||
2678 | |||
2679 | intsn = octeon_irq_ciu3_mbox_intsn_for_cpu(cpu, mbox); | ||
2680 | ciu3_info = per_cpu(octeon_ciu3_info, cpu); | ||
2681 | isc_w1s_addr = ciu3_info->ciu3_addr + CIU3_ISC_W1S(intsn); | ||
2682 | |||
2683 | isc_w1s.u64 = 0; | ||
2684 | isc_w1s.s.raw = 1; | ||
2685 | |||
2686 | cvmx_write_csr(isc_w1s_addr, isc_w1s.u64); | ||
2687 | cvmx_read_csr(isc_w1s_addr); | ||
2688 | } | ||
2689 | |||
2690 | static void octeon_irq_ciu3_mbox_set_enable(struct irq_data *data, int cpu, bool en) | ||
2691 | { | ||
2692 | struct octeon_ciu3_info *ciu3_info; | ||
2693 | unsigned int intsn; | ||
2694 | u64 isc_ctl_addr, isc_w1c_addr; | ||
2695 | union cvmx_ciu3_iscx_ctl isc_ctl; | ||
2696 | unsigned int mbox = data->irq - OCTEON_IRQ_MBOX0; | ||
2697 | |||
2698 | intsn = octeon_irq_ciu3_mbox_intsn_for_cpu(cpu, mbox); | ||
2699 | ciu3_info = per_cpu(octeon_ciu3_info, cpu); | ||
2700 | isc_w1c_addr = ciu3_info->ciu3_addr + CIU3_ISC_W1C(intsn); | ||
2701 | isc_ctl_addr = ciu3_info->ciu3_addr + CIU3_ISC_CTL(intsn); | ||
2702 | |||
2703 | isc_ctl.u64 = 0; | ||
2704 | isc_ctl.s.en = 1; | ||
2705 | |||
2706 | cvmx_write_csr(isc_w1c_addr, isc_ctl.u64); | ||
2707 | cvmx_write_csr(isc_ctl_addr, 0); | ||
2708 | if (en) { | ||
2709 | unsigned int idt = per_cpu(octeon_irq_ciu3_idt_ip3, cpu); | ||
2710 | |||
2711 | isc_ctl.u64 = 0; | ||
2712 | isc_ctl.s.en = 1; | ||
2713 | isc_ctl.s.idt = idt; | ||
2714 | cvmx_write_csr(isc_ctl_addr, isc_ctl.u64); | ||
2715 | } | ||
2716 | cvmx_read_csr(isc_ctl_addr); | ||
2717 | } | ||
2718 | |||
2719 | static void octeon_irq_ciu3_mbox_enable(struct irq_data *data) | ||
2720 | { | ||
2721 | int cpu; | ||
2722 | unsigned int mbox = data->irq - OCTEON_IRQ_MBOX0; | ||
2723 | |||
2724 | WARN_ON(mbox >= CIU3_MBOX_PER_CORE); | ||
2725 | |||
2726 | for_each_online_cpu(cpu) | ||
2727 | octeon_irq_ciu3_mbox_set_enable(data, cpu, true); | ||
2728 | } | ||
2729 | |||
2730 | static void octeon_irq_ciu3_mbox_disable(struct irq_data *data) | ||
2731 | { | ||
2732 | int cpu; | ||
2733 | unsigned int mbox = data->irq - OCTEON_IRQ_MBOX0; | ||
2734 | |||
2735 | WARN_ON(mbox >= CIU3_MBOX_PER_CORE); | ||
2736 | |||
2737 | for_each_online_cpu(cpu) | ||
2738 | octeon_irq_ciu3_mbox_set_enable(data, cpu, false); | ||
2739 | } | ||
2740 | |||
2741 | static void octeon_irq_ciu3_mbox_ack(struct irq_data *data) | ||
2742 | { | ||
2743 | struct octeon_ciu3_info *ciu3_info; | ||
2744 | unsigned int intsn; | ||
2745 | u64 isc_w1c_addr; | ||
2746 | union cvmx_ciu3_iscx_w1c isc_w1c; | ||
2747 | unsigned int mbox = data->irq - OCTEON_IRQ_MBOX0; | ||
2748 | |||
2749 | intsn = octeon_irq_ciu3_mbox_intsn_for_core(cvmx_get_local_core_num(), mbox); | ||
2750 | |||
2751 | isc_w1c.u64 = 0; | ||
2752 | isc_w1c.s.raw = 1; | ||
2753 | |||
2754 | ciu3_info = __this_cpu_read(octeon_ciu3_info); | ||
2755 | isc_w1c_addr = ciu3_info->ciu3_addr + CIU3_ISC_W1C(intsn); | ||
2756 | cvmx_write_csr(isc_w1c_addr, isc_w1c.u64); | ||
2757 | cvmx_read_csr(isc_w1c_addr); | ||
2758 | } | ||
2759 | |||
2760 | static void octeon_irq_ciu3_mbox_cpu_online(struct irq_data *data) | ||
2761 | { | ||
2762 | octeon_irq_ciu3_mbox_set_enable(data, smp_processor_id(), true); | ||
2763 | } | ||
2764 | |||
2765 | static void octeon_irq_ciu3_mbox_cpu_offline(struct irq_data *data) | ||
2766 | { | ||
2767 | octeon_irq_ciu3_mbox_set_enable(data, smp_processor_id(), false); | ||
2768 | } | ||
2769 | |||
2770 | static int octeon_irq_ciu3_alloc_resources(struct octeon_ciu3_info *ciu3_info) | ||
2771 | { | ||
2772 | u64 b = ciu3_info->ciu3_addr; | ||
2773 | int idt_ip2, idt_ip3, idt_ip4; | ||
2774 | int unused_idt2; | ||
2775 | int core = cvmx_get_local_core_num(); | ||
2776 | int i; | ||
2777 | |||
2778 | __this_cpu_write(octeon_ciu3_info, ciu3_info); | ||
2779 | |||
2780 | /* | ||
2781 | * 4 idt per core starting from 1 because zero is reserved. | ||
2782 | * Base idt per core is 4 * core + 1 | ||
2783 | */ | ||
2784 | idt_ip2 = core * 4 + 1; | ||
2785 | idt_ip3 = core * 4 + 2; | ||
2786 | idt_ip4 = core * 4 + 3; | ||
2787 | unused_idt2 = core * 4 + 4; | ||
2788 | __this_cpu_write(octeon_irq_ciu3_idt_ip2, idt_ip2); | ||
2789 | __this_cpu_write(octeon_irq_ciu3_idt_ip3, idt_ip3); | ||
2790 | |||
2791 | /* ip2 interrupts for this CPU */ | ||
2792 | cvmx_write_csr(b + CIU3_IDT_CTL(idt_ip2), 0); | ||
2793 | cvmx_write_csr(b + CIU3_IDT_PP(idt_ip2, 0), 1ull << core); | ||
2794 | cvmx_write_csr(b + CIU3_IDT_IO(idt_ip2), 0); | ||
2795 | |||
2796 | /* ip3 interrupts for this CPU */ | ||
2797 | cvmx_write_csr(b + CIU3_IDT_CTL(idt_ip3), 1); | ||
2798 | cvmx_write_csr(b + CIU3_IDT_PP(idt_ip3, 0), 1ull << core); | ||
2799 | cvmx_write_csr(b + CIU3_IDT_IO(idt_ip3), 0); | ||
2800 | |||
2801 | /* ip4 interrupts for this CPU */ | ||
2802 | cvmx_write_csr(b + CIU3_IDT_CTL(idt_ip4), 2); | ||
2803 | cvmx_write_csr(b + CIU3_IDT_PP(idt_ip4, 0), 0); | ||
2804 | cvmx_write_csr(b + CIU3_IDT_IO(idt_ip4), 0); | ||
2805 | |||
2806 | cvmx_write_csr(b + CIU3_IDT_CTL(unused_idt2), 0); | ||
2807 | cvmx_write_csr(b + CIU3_IDT_PP(unused_idt2, 0), 0); | ||
2808 | cvmx_write_csr(b + CIU3_IDT_IO(unused_idt2), 0); | ||
2809 | |||
2810 | for (i = 0; i < CIU3_MBOX_PER_CORE; i++) { | ||
2811 | unsigned int intsn = octeon_irq_ciu3_mbox_intsn_for_core(core, i); | ||
2812 | |||
2813 | cvmx_write_csr(b + CIU3_ISC_W1C(intsn), 2); | ||
2814 | cvmx_write_csr(b + CIU3_ISC_CTL(intsn), 0); | ||
2815 | } | ||
2816 | |||
2817 | return 0; | ||
2818 | } | ||
2819 | |||
2820 | static void octeon_irq_setup_secondary_ciu3(void) | ||
2821 | { | ||
2822 | struct octeon_ciu3_info *ciu3_info; | ||
2823 | |||
2824 | ciu3_info = octeon_ciu3_info_per_node[cvmx_get_node_num()]; | ||
2825 | octeon_irq_ciu3_alloc_resources(ciu3_info); | ||
2826 | irq_cpu_online(); | ||
2827 | |||
2828 | /* Enable the CIU lines */ | ||
2829 | set_c0_status(STATUSF_IP3 | STATUSF_IP2); | ||
2830 | if (octeon_irq_use_ip4) | ||
2831 | set_c0_status(STATUSF_IP4); | ||
2832 | else | ||
2833 | clear_c0_status(STATUSF_IP4); | ||
2834 | } | ||
2835 | |||
2836 | static struct irq_chip octeon_irq_chip_ciu3_mbox = { | ||
2837 | .name = "CIU3-M", | ||
2838 | .irq_enable = octeon_irq_ciu3_mbox_enable, | ||
2839 | .irq_disable = octeon_irq_ciu3_mbox_disable, | ||
2840 | .irq_ack = octeon_irq_ciu3_mbox_ack, | ||
2841 | |||
2842 | .irq_cpu_online = octeon_irq_ciu3_mbox_cpu_online, | ||
2843 | .irq_cpu_offline = octeon_irq_ciu3_mbox_cpu_offline, | ||
2844 | .flags = IRQCHIP_ONOFFLINE_ENABLED, | ||
2845 | }; | ||
2846 | |||
2847 | static int __init octeon_irq_init_ciu3(struct device_node *ciu_node, | ||
2848 | struct device_node *parent) | ||
2849 | { | ||
2850 | int i; | ||
2851 | int node; | ||
2852 | struct irq_domain *domain; | ||
2853 | struct octeon_ciu3_info *ciu3_info; | ||
2854 | const __be32 *zero_addr; | ||
2855 | u64 base_addr; | ||
2856 | union cvmx_ciu3_const consts; | ||
2857 | |||
2858 | node = 0; /* of_node_to_nid(ciu_node); */ | ||
2859 | ciu3_info = kzalloc_node(sizeof(*ciu3_info), GFP_KERNEL, node); | ||
2860 | |||
2861 | if (!ciu3_info) | ||
2862 | return -ENOMEM; | ||
2863 | |||
2864 | zero_addr = of_get_address(ciu_node, 0, NULL, NULL); | ||
2865 | if (WARN_ON(!zero_addr)) | ||
2866 | return -EINVAL; | ||
2867 | |||
2868 | base_addr = of_translate_address(ciu_node, zero_addr); | ||
2869 | base_addr = (u64)phys_to_virt(base_addr); | ||
2870 | |||
2871 | ciu3_info->ciu3_addr = base_addr; | ||
2872 | ciu3_info->node = node; | ||
2873 | |||
2874 | consts.u64 = cvmx_read_csr(base_addr + CIU3_CONST); | ||
2875 | |||
2876 | octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu3; | ||
2877 | |||
2878 | octeon_irq_ip2 = octeon_irq_ciu3_ip2; | ||
2879 | octeon_irq_ip3 = octeon_irq_ciu3_mbox; | ||
2880 | octeon_irq_ip4 = octeon_irq_ip4_mask; | ||
2881 | |||
2882 | if (node == cvmx_get_node_num()) { | ||
2883 | /* Mips internal */ | ||
2884 | octeon_irq_init_core(); | ||
2885 | |||
2886 | /* Only do per CPU things if it is the CIU of the boot node. */ | ||
2887 | i = irq_alloc_descs_from(OCTEON_IRQ_MBOX0, 8, node); | ||
2888 | WARN_ON(i < 0); | ||
2889 | |||
2890 | for (i = 0; i < 8; i++) | ||
2891 | irq_set_chip_and_handler(i + OCTEON_IRQ_MBOX0, | ||
2892 | &octeon_irq_chip_ciu3_mbox, handle_percpu_irq); | ||
2893 | } | ||
2894 | |||
2895 | /* | ||
2896 | * Initialize all domains to use the default domain. Specific major | ||
2897 | * blocks will overwrite the default domain as needed. | ||
2898 | */ | ||
2899 | domain = irq_domain_add_tree(ciu_node, &octeon_dflt_domain_ciu3_ops, | ||
2900 | ciu3_info); | ||
2901 | for (i = 0; i < MAX_CIU3_DOMAINS; i++) | ||
2902 | ciu3_info->domain[i] = domain; | ||
2903 | |||
2904 | octeon_ciu3_info_per_node[node] = ciu3_info; | ||
2905 | |||
2906 | if (node == cvmx_get_node_num()) { | ||
2907 | /* Only do per CPU things if it is the CIU of the boot node. */ | ||
2908 | octeon_irq_ciu3_alloc_resources(ciu3_info); | ||
2909 | if (node == 0) | ||
2910 | irq_set_default_host(domain); | ||
2911 | |||
2912 | octeon_irq_use_ip4 = false; | ||
2913 | /* Enable the CIU lines */ | ||
2914 | set_c0_status(STATUSF_IP2 | STATUSF_IP3); | ||
2915 | clear_c0_status(STATUSF_IP4); | ||
2916 | } | ||
2917 | |||
2918 | return 0; | ||
2919 | } | ||
2920 | |||
2297 | static struct of_device_id ciu_types[] __initdata = { | 2921 | static struct of_device_id ciu_types[] __initdata = { |
2298 | {.compatible = "cavium,octeon-3860-ciu", .data = octeon_irq_init_ciu}, | 2922 | {.compatible = "cavium,octeon-3860-ciu", .data = octeon_irq_init_ciu}, |
2299 | {.compatible = "cavium,octeon-3860-gpio", .data = octeon_irq_init_gpio}, | 2923 | {.compatible = "cavium,octeon-3860-gpio", .data = octeon_irq_init_gpio}, |
2300 | {.compatible = "cavium,octeon-6880-ciu2", .data = octeon_irq_init_ciu2}, | 2924 | {.compatible = "cavium,octeon-6880-ciu2", .data = octeon_irq_init_ciu2}, |
2925 | {.compatible = "cavium,octeon-7890-ciu3", .data = octeon_irq_init_ciu3}, | ||
2301 | {.compatible = "cavium,octeon-7130-cib", .data = octeon_irq_init_cib}, | 2926 | {.compatible = "cavium,octeon-7130-cib", .data = octeon_irq_init_cib}, |
2302 | {} | 2927 | {} |
2303 | }; | 2928 | }; |
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index d113c8ded6e2..7aeafedff94e 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
14 | #include <linux/usb.h> | 14 | #include <linux/usb.h> |
15 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
16 | #include <linux/etherdevice.h> | ||
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -525,10 +526,17 @@ static void __init octeon_fdt_set_phy(int eth, int phy_addr) | |||
525 | 526 | ||
526 | static void __init octeon_fdt_set_mac_addr(int n, u64 *pmac) | 527 | static void __init octeon_fdt_set_mac_addr(int n, u64 *pmac) |
527 | { | 528 | { |
529 | const u8 *old_mac; | ||
530 | int old_len; | ||
528 | u8 new_mac[6]; | 531 | u8 new_mac[6]; |
529 | u64 mac = *pmac; | 532 | u64 mac = *pmac; |
530 | int r; | 533 | int r; |
531 | 534 | ||
535 | old_mac = fdt_getprop(initial_boot_params, n, "local-mac-address", | ||
536 | &old_len); | ||
537 | if (!old_mac || old_len != 6 || is_valid_ether_addr(old_mac)) | ||
538 | return; | ||
539 | |||
532 | new_mac[0] = (mac >> 40) & 0xff; | 540 | new_mac[0] = (mac >> 40) & 0xff; |
533 | new_mac[1] = (mac >> 32) & 0xff; | 541 | new_mac[1] = (mac >> 32) & 0xff; |
534 | new_mac[2] = (mac >> 24) & 0xff; | 542 | new_mac[2] = (mac >> 24) & 0xff; |
@@ -560,7 +568,7 @@ static void __init octeon_fdt_rm_ethernet(int node) | |||
560 | fdt_nop_node(initial_boot_params, node); | 568 | fdt_nop_node(initial_boot_params, node); |
561 | } | 569 | } |
562 | 570 | ||
563 | static void __init octeon_fdt_pip_port(int iface, int i, int p, int max, u64 *pmac) | 571 | static void __init octeon_fdt_pip_port(int iface, int i, int p, int max) |
564 | { | 572 | { |
565 | char name_buffer[20]; | 573 | char name_buffer[20]; |
566 | int eth; | 574 | int eth; |
@@ -583,10 +591,9 @@ static void __init octeon_fdt_pip_port(int iface, int i, int p, int max, u64 *pm | |||
583 | 591 | ||
584 | phy_addr = cvmx_helper_board_get_mii_address(ipd_port); | 592 | phy_addr = cvmx_helper_board_get_mii_address(ipd_port); |
585 | octeon_fdt_set_phy(eth, phy_addr); | 593 | octeon_fdt_set_phy(eth, phy_addr); |
586 | octeon_fdt_set_mac_addr(eth, pmac); | ||
587 | } | 594 | } |
588 | 595 | ||
589 | static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac) | 596 | static void __init octeon_fdt_pip_iface(int pip, int idx) |
590 | { | 597 | { |
591 | char name_buffer[20]; | 598 | char name_buffer[20]; |
592 | int iface; | 599 | int iface; |
@@ -602,7 +609,73 @@ static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac) | |||
602 | count = cvmx_helper_ports_on_interface(idx); | 609 | count = cvmx_helper_ports_on_interface(idx); |
603 | 610 | ||
604 | for (p = 0; p < 16; p++) | 611 | for (p = 0; p < 16; p++) |
605 | octeon_fdt_pip_port(iface, idx, p, count - 1, pmac); | 612 | octeon_fdt_pip_port(iface, idx, p, count - 1); |
613 | } | ||
614 | |||
615 | void __init octeon_fill_mac_addresses(void) | ||
616 | { | ||
617 | const char *alias_prop; | ||
618 | char name_buffer[20]; | ||
619 | u64 mac_addr_base; | ||
620 | int aliases; | ||
621 | int pip; | ||
622 | int i; | ||
623 | |||
624 | aliases = fdt_path_offset(initial_boot_params, "/aliases"); | ||
625 | if (aliases < 0) | ||
626 | return; | ||
627 | |||
628 | mac_addr_base = | ||
629 | ((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 | | ||
630 | ((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 | | ||
631 | ((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 | | ||
632 | ((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 | | ||
633 | ((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 | | ||
634 | (octeon_bootinfo->mac_addr_base[5] & 0xffull); | ||
635 | |||
636 | for (i = 0; i < 2; i++) { | ||
637 | int mgmt; | ||
638 | |||
639 | snprintf(name_buffer, sizeof(name_buffer), "mix%d", i); | ||
640 | alias_prop = fdt_getprop(initial_boot_params, aliases, | ||
641 | name_buffer, NULL); | ||
642 | if (!alias_prop) | ||
643 | continue; | ||
644 | mgmt = fdt_path_offset(initial_boot_params, alias_prop); | ||
645 | if (mgmt < 0) | ||
646 | continue; | ||
647 | octeon_fdt_set_mac_addr(mgmt, &mac_addr_base); | ||
648 | } | ||
649 | |||
650 | alias_prop = fdt_getprop(initial_boot_params, aliases, "pip", NULL); | ||
651 | if (!alias_prop) | ||
652 | return; | ||
653 | |||
654 | pip = fdt_path_offset(initial_boot_params, alias_prop); | ||
655 | if (pip < 0) | ||
656 | return; | ||
657 | |||
658 | for (i = 0; i <= 4; i++) { | ||
659 | int iface; | ||
660 | int p; | ||
661 | |||
662 | snprintf(name_buffer, sizeof(name_buffer), "interface@%d", i); | ||
663 | iface = fdt_subnode_offset(initial_boot_params, pip, | ||
664 | name_buffer); | ||
665 | if (iface < 0) | ||
666 | continue; | ||
667 | for (p = 0; p < 16; p++) { | ||
668 | int eth; | ||
669 | |||
670 | snprintf(name_buffer, sizeof(name_buffer), | ||
671 | "ethernet@%x", p); | ||
672 | eth = fdt_subnode_offset(initial_boot_params, iface, | ||
673 | name_buffer); | ||
674 | if (eth < 0) | ||
675 | continue; | ||
676 | octeon_fdt_set_mac_addr(eth, &mac_addr_base); | ||
677 | } | ||
678 | } | ||
606 | } | 679 | } |
607 | 680 | ||
608 | int __init octeon_prune_device_tree(void) | 681 | int __init octeon_prune_device_tree(void) |
@@ -612,7 +685,6 @@ int __init octeon_prune_device_tree(void) | |||
612 | const char *alias_prop; | 685 | const char *alias_prop; |
613 | char name_buffer[20]; | 686 | char name_buffer[20]; |
614 | int aliases; | 687 | int aliases; |
615 | u64 mac_addr_base; | ||
616 | 688 | ||
617 | if (fdt_check_header(initial_boot_params)) | 689 | if (fdt_check_header(initial_boot_params)) |
618 | panic("Corrupt Device Tree."); | 690 | panic("Corrupt Device Tree."); |
@@ -623,15 +695,6 @@ int __init octeon_prune_device_tree(void) | |||
623 | return -EINVAL; | 695 | return -EINVAL; |
624 | } | 696 | } |
625 | 697 | ||
626 | |||
627 | mac_addr_base = | ||
628 | ((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 | | ||
629 | ((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 | | ||
630 | ((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 | | ||
631 | ((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 | | ||
632 | ((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 | | ||
633 | (octeon_bootinfo->mac_addr_base[5] & 0xffull); | ||
634 | |||
635 | if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN63XX)) | 698 | if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN63XX)) |
636 | max_port = 2; | 699 | max_port = 2; |
637 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN68XX)) | 700 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN68XX)) |
@@ -660,7 +723,6 @@ int __init octeon_prune_device_tree(void) | |||
660 | } else { | 723 | } else { |
661 | int phy_addr = cvmx_helper_board_get_mii_address(CVMX_HELPER_BOARD_MGMT_IPD_PORT + i); | 724 | int phy_addr = cvmx_helper_board_get_mii_address(CVMX_HELPER_BOARD_MGMT_IPD_PORT + i); |
662 | octeon_fdt_set_phy(mgmt, phy_addr); | 725 | octeon_fdt_set_phy(mgmt, phy_addr); |
663 | octeon_fdt_set_mac_addr(mgmt, &mac_addr_base); | ||
664 | } | 726 | } |
665 | } | 727 | } |
666 | } | 728 | } |
@@ -670,7 +732,7 @@ int __init octeon_prune_device_tree(void) | |||
670 | int pip = fdt_path_offset(initial_boot_params, pip_path); | 732 | int pip = fdt_path_offset(initial_boot_params, pip_path); |
671 | if (pip >= 0) | 733 | if (pip >= 0) |
672 | for (i = 0; i <= 4; i++) | 734 | for (i = 0; i <= 4; i++) |
673 | octeon_fdt_pip_iface(pip, i, &mac_addr_base); | 735 | octeon_fdt_pip_iface(pip, i); |
674 | } | 736 | } |
675 | 737 | ||
676 | /* I2C */ | 738 | /* I2C */ |
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index cd7101fb6227..64f852b063a8 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c | |||
@@ -43,8 +43,6 @@ | |||
43 | #include <asm/octeon/cvmx-mio-defs.h> | 43 | #include <asm/octeon/cvmx-mio-defs.h> |
44 | #include <asm/octeon/cvmx-rst-defs.h> | 44 | #include <asm/octeon/cvmx-rst-defs.h> |
45 | 45 | ||
46 | extern struct plat_smp_ops octeon_smp_ops; | ||
47 | |||
48 | #ifdef CONFIG_PCI | 46 | #ifdef CONFIG_PCI |
49 | extern void pci_console_init(const char *arg); | 47 | extern void pci_console_init(const char *arg); |
50 | #endif | 48 | #endif |
@@ -466,15 +464,25 @@ static void octeon_halt(void) | |||
466 | 464 | ||
467 | static char __read_mostly octeon_system_type[80]; | 465 | static char __read_mostly octeon_system_type[80]; |
468 | 466 | ||
469 | static int __init init_octeon_system_type(void) | 467 | static void __init init_octeon_system_type(void) |
470 | { | 468 | { |
471 | snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)", | 469 | char const *board_type; |
472 | cvmx_board_type_to_string(octeon_bootinfo->board_type), | 470 | |
473 | octeon_model_get_string(read_c0_prid())); | 471 | board_type = cvmx_board_type_to_string(octeon_bootinfo->board_type); |
472 | if (board_type == NULL) { | ||
473 | struct device_node *root; | ||
474 | int ret; | ||
475 | |||
476 | root = of_find_node_by_path("/"); | ||
477 | ret = of_property_read_string(root, "model", &board_type); | ||
478 | of_node_put(root); | ||
479 | if (ret) | ||
480 | board_type = "Unsupported Board"; | ||
481 | } | ||
474 | 482 | ||
475 | return 0; | 483 | snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)", |
484 | board_type, octeon_model_get_string(read_c0_prid())); | ||
476 | } | 485 | } |
477 | early_initcall(init_octeon_system_type); | ||
478 | 486 | ||
479 | /** | 487 | /** |
480 | * Return a string representing the system type | 488 | * Return a string representing the system type |
@@ -492,8 +500,6 @@ const char *get_system_type(void) | |||
492 | void octeon_user_io_init(void) | 500 | void octeon_user_io_init(void) |
493 | { | 501 | { |
494 | union octeon_cvmemctl cvmmemctl; | 502 | union octeon_cvmemctl cvmmemctl; |
495 | union cvmx_iob_fau_timeout fau_timeout; | ||
496 | union cvmx_pow_nw_tim nm_tim; | ||
497 | 503 | ||
498 | /* Get the current settings for CP0_CVMMEMCTL_REG */ | 504 | /* Get the current settings for CP0_CVMMEMCTL_REG */ |
499 | cvmmemctl.u64 = read_c0_cvmmemctl(); | 505 | cvmmemctl.u64 = read_c0_cvmmemctl(); |
@@ -595,17 +601,27 @@ void octeon_user_io_init(void) | |||
595 | CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE, | 601 | CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE, |
596 | CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128); | 602 | CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128); |
597 | 603 | ||
598 | /* Set a default for the hardware timeouts */ | 604 | if (octeon_has_feature(OCTEON_FEATURE_FAU)) { |
599 | fau_timeout.u64 = 0; | 605 | union cvmx_iob_fau_timeout fau_timeout; |
600 | fau_timeout.s.tout_val = 0xfff; | 606 | |
601 | /* Disable tagwait FAU timeout */ | 607 | /* Set a default for the hardware timeouts */ |
602 | fau_timeout.s.tout_enb = 0; | 608 | fau_timeout.u64 = 0; |
603 | cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64); | 609 | fau_timeout.s.tout_val = 0xfff; |
610 | /* Disable tagwait FAU timeout */ | ||
611 | fau_timeout.s.tout_enb = 0; | ||
612 | cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64); | ||
613 | } | ||
604 | 614 | ||
605 | nm_tim.u64 = 0; | 615 | if ((!OCTEON_IS_MODEL(OCTEON_CN68XX) && |
606 | /* 4096 cycles */ | 616 | !OCTEON_IS_MODEL(OCTEON_CN7XXX)) || |
607 | nm_tim.s.nw_tim = 3; | 617 | OCTEON_IS_MODEL(OCTEON_CN70XX)) { |
608 | cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64); | 618 | union cvmx_pow_nw_tim nm_tim; |
619 | |||
620 | nm_tim.u64 = 0; | ||
621 | /* 4096 cycles */ | ||
622 | nm_tim.s.nw_tim = 3; | ||
623 | cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64); | ||
624 | } | ||
609 | 625 | ||
610 | write_octeon_c0_icacheerr(0); | 626 | write_octeon_c0_icacheerr(0); |
611 | write_c0_derraddr1(0); | 627 | write_c0_derraddr1(0); |
@@ -637,9 +653,22 @@ void __init prom_init(void) | |||
637 | sysinfo = cvmx_sysinfo_get(); | 653 | sysinfo = cvmx_sysinfo_get(); |
638 | memset(sysinfo, 0, sizeof(*sysinfo)); | 654 | memset(sysinfo, 0, sizeof(*sysinfo)); |
639 | sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20; | 655 | sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20; |
640 | sysinfo->phy_mem_desc_ptr = | 656 | sysinfo->phy_mem_desc_addr = (u64)phys_to_virt(octeon_bootinfo->phy_mem_desc_addr); |
641 | cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr); | 657 | |
642 | sysinfo->core_mask = octeon_bootinfo->core_mask; | 658 | if ((octeon_bootinfo->major_version > 1) || |
659 | (octeon_bootinfo->major_version == 1 && | ||
660 | octeon_bootinfo->minor_version >= 4)) | ||
661 | cvmx_coremask_copy(&sysinfo->core_mask, | ||
662 | &octeon_bootinfo->ext_core_mask); | ||
663 | else | ||
664 | cvmx_coremask_set64(&sysinfo->core_mask, | ||
665 | octeon_bootinfo->core_mask); | ||
666 | |||
667 | /* Some broken u-boot pass garbage in upper bits, clear them out */ | ||
668 | if (!OCTEON_IS_MODEL(OCTEON_CN78XX)) | ||
669 | for (i = 512; i < 1024; i++) | ||
670 | cvmx_coremask_clear_core(&sysinfo->core_mask, i); | ||
671 | |||
643 | sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr; | 672 | sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr; |
644 | sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz; | 673 | sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz; |
645 | sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2; | 674 | sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2; |
@@ -867,7 +896,7 @@ void __init prom_init(void) | |||
867 | #endif | 896 | #endif |
868 | 897 | ||
869 | octeon_user_io_init(); | 898 | octeon_user_io_init(); |
870 | register_smp_ops(&octeon_smp_ops); | 899 | octeon_setup_smp(); |
871 | } | 900 | } |
872 | 901 | ||
873 | /* Exclude a single page from the regions obtained in plat_mem_setup. */ | 902 | /* Exclude a single page from the regions obtained in plat_mem_setup. */ |
@@ -1079,6 +1108,7 @@ void __init prom_free_prom_memory(void) | |||
1079 | } | 1108 | } |
1080 | } | 1109 | } |
1081 | 1110 | ||
1111 | void __init octeon_fill_mac_addresses(void); | ||
1082 | int octeon_prune_device_tree(void); | 1112 | int octeon_prune_device_tree(void); |
1083 | 1113 | ||
1084 | extern const char __appended_dtb; | 1114 | extern const char __appended_dtb; |
@@ -1088,11 +1118,13 @@ void __init device_tree_init(void) | |||
1088 | { | 1118 | { |
1089 | const void *fdt; | 1119 | const void *fdt; |
1090 | bool do_prune; | 1120 | bool do_prune; |
1121 | bool fill_mac; | ||
1091 | 1122 | ||
1092 | #ifdef CONFIG_MIPS_ELF_APPENDED_DTB | 1123 | #ifdef CONFIG_MIPS_ELF_APPENDED_DTB |
1093 | if (!fdt_check_header(&__appended_dtb)) { | 1124 | if (!fdt_check_header(&__appended_dtb)) { |
1094 | fdt = &__appended_dtb; | 1125 | fdt = &__appended_dtb; |
1095 | do_prune = false; | 1126 | do_prune = false; |
1127 | fill_mac = true; | ||
1096 | pr_info("Using appended Device Tree.\n"); | 1128 | pr_info("Using appended Device Tree.\n"); |
1097 | } else | 1129 | } else |
1098 | #endif | 1130 | #endif |
@@ -1101,13 +1133,16 @@ void __init device_tree_init(void) | |||
1101 | if (fdt_check_header(fdt)) | 1133 | if (fdt_check_header(fdt)) |
1102 | panic("Corrupt Device Tree passed to kernel."); | 1134 | panic("Corrupt Device Tree passed to kernel."); |
1103 | do_prune = false; | 1135 | do_prune = false; |
1136 | fill_mac = false; | ||
1104 | pr_info("Using passed Device Tree.\n"); | 1137 | pr_info("Using passed Device Tree.\n"); |
1105 | } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { | 1138 | } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { |
1106 | fdt = &__dtb_octeon_68xx_begin; | 1139 | fdt = &__dtb_octeon_68xx_begin; |
1107 | do_prune = true; | 1140 | do_prune = true; |
1141 | fill_mac = true; | ||
1108 | } else { | 1142 | } else { |
1109 | fdt = &__dtb_octeon_3xxx_begin; | 1143 | fdt = &__dtb_octeon_3xxx_begin; |
1110 | do_prune = true; | 1144 | do_prune = true; |
1145 | fill_mac = true; | ||
1111 | } | 1146 | } |
1112 | 1147 | ||
1113 | initial_boot_params = (void *)fdt; | 1148 | initial_boot_params = (void *)fdt; |
@@ -1116,7 +1151,10 @@ void __init device_tree_init(void) | |||
1116 | octeon_prune_device_tree(); | 1151 | octeon_prune_device_tree(); |
1117 | pr_info("Using internal Device Tree.\n"); | 1152 | pr_info("Using internal Device Tree.\n"); |
1118 | } | 1153 | } |
1154 | if (fill_mac) | ||
1155 | octeon_fill_mac_addresses(); | ||
1119 | unflatten_and_copy_device_tree(); | 1156 | unflatten_and_copy_device_tree(); |
1157 | init_octeon_system_type(); | ||
1120 | } | 1158 | } |
1121 | 1159 | ||
1122 | static int __initdata disable_octeon_edac_p; | 1160 | static int __initdata disable_octeon_edac_p; |
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 42412ba0f3bf..dff88aa7e377 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c | |||
@@ -30,25 +30,55 @@ uint64_t octeon_bootloader_entry_addr; | |||
30 | EXPORT_SYMBOL(octeon_bootloader_entry_addr); | 30 | EXPORT_SYMBOL(octeon_bootloader_entry_addr); |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | static void octeon_icache_flush(void) | ||
34 | { | ||
35 | asm volatile ("synci 0($0)\n"); | ||
36 | } | ||
37 | |||
38 | static void (*octeon_message_functions[8])(void) = { | ||
39 | scheduler_ipi, | ||
40 | generic_smp_call_function_interrupt, | ||
41 | octeon_icache_flush, | ||
42 | }; | ||
43 | |||
33 | static irqreturn_t mailbox_interrupt(int irq, void *dev_id) | 44 | static irqreturn_t mailbox_interrupt(int irq, void *dev_id) |
34 | { | 45 | { |
35 | const int coreid = cvmx_get_core_num(); | 46 | u64 mbox_clrx = CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()); |
36 | uint64_t action; | 47 | u64 action; |
48 | int i; | ||
49 | |||
50 | /* | ||
51 | * Make sure the function array initialization remains | ||
52 | * correct. | ||
53 | */ | ||
54 | BUILD_BUG_ON(SMP_RESCHEDULE_YOURSELF != (1 << 0)); | ||
55 | BUILD_BUG_ON(SMP_CALL_FUNCTION != (1 << 1)); | ||
56 | BUILD_BUG_ON(SMP_ICACHE_FLUSH != (1 << 2)); | ||
57 | |||
58 | /* | ||
59 | * Load the mailbox register to figure out what we're supposed | ||
60 | * to do. | ||
61 | */ | ||
62 | action = cvmx_read_csr(mbox_clrx); | ||
37 | 63 | ||
38 | /* Load the mailbox register to figure out what we're supposed to do */ | 64 | if (OCTEON_IS_MODEL(OCTEON_CN68XX)) |
39 | action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)) & 0xffff; | 65 | action &= 0xff; |
66 | else | ||
67 | action &= 0xffff; | ||
40 | 68 | ||
41 | /* Clear the mailbox to clear the interrupt */ | 69 | /* Clear the mailbox to clear the interrupt */ |
42 | cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action); | 70 | cvmx_write_csr(mbox_clrx, action); |
43 | 71 | ||
44 | if (action & SMP_CALL_FUNCTION) | 72 | for (i = 0; i < ARRAY_SIZE(octeon_message_functions) && action;) { |
45 | generic_smp_call_function_interrupt(); | 73 | if (action & 1) { |
46 | if (action & SMP_RESCHEDULE_YOURSELF) | 74 | void (*fn)(void) = octeon_message_functions[i]; |
47 | scheduler_ipi(); | ||
48 | 75 | ||
49 | /* Check if we've been told to flush the icache */ | 76 | if (fn) |
50 | if (action & SMP_ICACHE_FLUSH) | 77 | fn(); |
51 | asm volatile ("synci 0($0)\n"); | 78 | } |
79 | action >>= 1; | ||
80 | i++; | ||
81 | } | ||
52 | return IRQ_HANDLED; | 82 | return IRQ_HANDLED; |
53 | } | 83 | } |
54 | 84 | ||
@@ -97,13 +127,15 @@ static void octeon_smp_hotplug_setup(void) | |||
97 | #endif | 127 | #endif |
98 | } | 128 | } |
99 | 129 | ||
100 | static void octeon_smp_setup(void) | 130 | static void __init octeon_smp_setup(void) |
101 | { | 131 | { |
102 | const int coreid = cvmx_get_core_num(); | 132 | const int coreid = cvmx_get_core_num(); |
103 | int cpus; | 133 | int cpus; |
104 | int id; | 134 | int id; |
105 | int core_mask = octeon_get_boot_coremask(); | 135 | struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get(); |
136 | |||
106 | #ifdef CONFIG_HOTPLUG_CPU | 137 | #ifdef CONFIG_HOTPLUG_CPU |
138 | int core_mask = octeon_get_boot_coremask(); | ||
107 | unsigned int num_cores = cvmx_octeon_num_cores(); | 139 | unsigned int num_cores = cvmx_octeon_num_cores(); |
108 | #endif | 140 | #endif |
109 | 141 | ||
@@ -119,7 +151,7 @@ static void octeon_smp_setup(void) | |||
119 | /* The present CPUs get the lowest CPU numbers. */ | 151 | /* The present CPUs get the lowest CPU numbers. */ |
120 | cpus = 1; | 152 | cpus = 1; |
121 | for (id = 0; id < NR_CPUS; id++) { | 153 | for (id = 0; id < NR_CPUS; id++) { |
122 | if ((id != coreid) && (core_mask & (1 << id))) { | 154 | if ((id != coreid) && cvmx_coremask_is_core_set(&sysinfo->core_mask, id)) { |
123 | set_cpu_possible(cpus, true); | 155 | set_cpu_possible(cpus, true); |
124 | set_cpu_present(cpus, true); | 156 | set_cpu_present(cpus, true); |
125 | __cpu_number_map[id] = cpus; | 157 | __cpu_number_map[id] = cpus; |
@@ -196,7 +228,7 @@ static void octeon_init_secondary(void) | |||
196 | * Callout to firmware before smp_init | 228 | * Callout to firmware before smp_init |
197 | * | 229 | * |
198 | */ | 230 | */ |
199 | void octeon_prepare_cpus(unsigned int max_cpus) | 231 | static void __init octeon_prepare_cpus(unsigned int max_cpus) |
200 | { | 232 | { |
201 | /* | 233 | /* |
202 | * Only the low order mailbox bits are used for IPIs, leave | 234 | * Only the low order mailbox bits are used for IPIs, leave |
@@ -242,7 +274,7 @@ static int octeon_cpu_disable(void) | |||
242 | cpumask_clear_cpu(cpu, &cpu_callin_map); | 274 | cpumask_clear_cpu(cpu, &cpu_callin_map); |
243 | octeon_fixup_irqs(); | 275 | octeon_fixup_irqs(); |
244 | 276 | ||
245 | flush_cache_all(); | 277 | __flush_cache_all(); |
246 | local_flush_tlb_all(); | 278 | local_flush_tlb_all(); |
247 | 279 | ||
248 | return 0; | 280 | return 0; |
@@ -388,3 +420,92 @@ struct plat_smp_ops octeon_smp_ops = { | |||
388 | .cpu_die = octeon_cpu_die, | 420 | .cpu_die = octeon_cpu_die, |
389 | #endif | 421 | #endif |
390 | }; | 422 | }; |
423 | |||
424 | static irqreturn_t octeon_78xx_reched_interrupt(int irq, void *dev_id) | ||
425 | { | ||
426 | scheduler_ipi(); | ||
427 | return IRQ_HANDLED; | ||
428 | } | ||
429 | |||
430 | static irqreturn_t octeon_78xx_call_function_interrupt(int irq, void *dev_id) | ||
431 | { | ||
432 | generic_smp_call_function_interrupt(); | ||
433 | return IRQ_HANDLED; | ||
434 | } | ||
435 | |||
436 | static irqreturn_t octeon_78xx_icache_flush_interrupt(int irq, void *dev_id) | ||
437 | { | ||
438 | octeon_icache_flush(); | ||
439 | return IRQ_HANDLED; | ||
440 | } | ||
441 | |||
442 | /* | ||
443 | * Callout to firmware before smp_init | ||
444 | */ | ||
445 | static void octeon_78xx_prepare_cpus(unsigned int max_cpus) | ||
446 | { | ||
447 | if (request_irq(OCTEON_IRQ_MBOX0 + 0, | ||
448 | octeon_78xx_reched_interrupt, | ||
449 | IRQF_PERCPU | IRQF_NO_THREAD, "Scheduler", | ||
450 | octeon_78xx_reched_interrupt)) { | ||
451 | panic("Cannot request_irq for SchedulerIPI"); | ||
452 | } | ||
453 | if (request_irq(OCTEON_IRQ_MBOX0 + 1, | ||
454 | octeon_78xx_call_function_interrupt, | ||
455 | IRQF_PERCPU | IRQF_NO_THREAD, "SMP-Call", | ||
456 | octeon_78xx_call_function_interrupt)) { | ||
457 | panic("Cannot request_irq for SMP-Call"); | ||
458 | } | ||
459 | if (request_irq(OCTEON_IRQ_MBOX0 + 2, | ||
460 | octeon_78xx_icache_flush_interrupt, | ||
461 | IRQF_PERCPU | IRQF_NO_THREAD, "ICache-Flush", | ||
462 | octeon_78xx_icache_flush_interrupt)) { | ||
463 | panic("Cannot request_irq for ICache-Flush"); | ||
464 | } | ||
465 | } | ||
466 | |||
467 | static void octeon_78xx_send_ipi_single(int cpu, unsigned int action) | ||
468 | { | ||
469 | int i; | ||
470 | |||
471 | for (i = 0; i < 8; i++) { | ||
472 | if (action & 1) | ||
473 | octeon_ciu3_mbox_send(cpu, i); | ||
474 | action >>= 1; | ||
475 | } | ||
476 | } | ||
477 | |||
478 | static void octeon_78xx_send_ipi_mask(const struct cpumask *mask, | ||
479 | unsigned int action) | ||
480 | { | ||
481 | unsigned int cpu; | ||
482 | |||
483 | for_each_cpu(cpu, mask) | ||
484 | octeon_78xx_send_ipi_single(cpu, action); | ||
485 | } | ||
486 | |||
487 | static struct plat_smp_ops octeon_78xx_smp_ops = { | ||
488 | .send_ipi_single = octeon_78xx_send_ipi_single, | ||
489 | .send_ipi_mask = octeon_78xx_send_ipi_mask, | ||
490 | .init_secondary = octeon_init_secondary, | ||
491 | .smp_finish = octeon_smp_finish, | ||
492 | .boot_secondary = octeon_boot_secondary, | ||
493 | .smp_setup = octeon_smp_setup, | ||
494 | .prepare_cpus = octeon_78xx_prepare_cpus, | ||
495 | #ifdef CONFIG_HOTPLUG_CPU | ||
496 | .cpu_disable = octeon_cpu_disable, | ||
497 | .cpu_die = octeon_cpu_die, | ||
498 | #endif | ||
499 | }; | ||
500 | |||
501 | void __init octeon_setup_smp(void) | ||
502 | { | ||
503 | struct plat_smp_ops *ops; | ||
504 | |||
505 | if (octeon_has_feature(OCTEON_FEATURE_CIU3)) | ||
506 | ops = &octeon_78xx_smp_ops; | ||
507 | else | ||
508 | ops = &octeon_smp_ops; | ||
509 | |||
510 | register_smp_ops(ops); | ||
511 | } | ||
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index 0db4eb319e0a..fad8e964f14c 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig | |||
@@ -23,7 +23,6 @@ CONFIG_IP_MROUTE=y | |||
23 | CONFIG_IP_MROUTE_MULTIPLE_TABLES=y | 23 | CONFIG_IP_MROUTE_MULTIPLE_TABLES=y |
24 | CONFIG_SYN_COOKIES=y | 24 | CONFIG_SYN_COOKIES=y |
25 | CONFIG_TCP_CONG_ADVANCED=y | 25 | CONFIG_TCP_CONG_ADVANCED=y |
26 | CONFIG_IPV6_PRIVACY=y | ||
27 | CONFIG_IPV6_MULTIPLE_TABLES=y | 26 | CONFIG_IPV6_MULTIPLE_TABLES=y |
28 | CONFIG_IPV6_SUBTREES=y | 27 | CONFIG_IPV6_SUBTREES=y |
29 | CONFIG_IPV6_MROUTE=y | 28 | CONFIG_IPV6_MROUTE=y |
diff --git a/arch/mips/configs/bcm63xx_defconfig b/arch/mips/configs/bcm63xx_defconfig index 3fec26410f34..5599a9f1e3c6 100644 --- a/arch/mips/configs/bcm63xx_defconfig +++ b/arch/mips/configs/bcm63xx_defconfig | |||
@@ -44,6 +44,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
44 | # CONFIG_STANDALONE is not set | 44 | # CONFIG_STANDALONE is not set |
45 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | 45 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
46 | CONFIG_MTD=y | 46 | CONFIG_MTD=y |
47 | CONFIG_MTD_BCM63XX_PARTS=y | ||
47 | CONFIG_MTD_CFI=y | 48 | CONFIG_MTD_CFI=y |
48 | CONFIG_MTD_CFI_INTELEXT=y | 49 | CONFIG_MTD_CFI_INTELEXT=y |
49 | CONFIG_MTD_CFI_AMDSTD=y | 50 | CONFIG_MTD_CFI_AMDSTD=y |
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index e070dac071c8..d20b09d77b53 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig | |||
@@ -62,7 +62,6 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m | |||
62 | CONFIG_INET_XFRM_MODE_TUNNEL=m | 62 | CONFIG_INET_XFRM_MODE_TUNNEL=m |
63 | # CONFIG_INET_LRO is not set | 63 | # CONFIG_INET_LRO is not set |
64 | CONFIG_TCP_MD5SIG=y | 64 | CONFIG_TCP_MD5SIG=y |
65 | CONFIG_IPV6_PRIVACY=y | ||
66 | CONFIG_IPV6_ROUTER_PREF=y | 65 | CONFIG_IPV6_ROUTER_PREF=y |
67 | CONFIG_IPV6_ROUTE_INFO=y | 66 | CONFIG_IPV6_ROUTE_INFO=y |
68 | CONFIG_IPV6_OPTIMISTIC_DAD=y | 67 | CONFIG_IPV6_OPTIMISTIC_DAD=y |
diff --git a/arch/mips/configs/bmips_be_defconfig b/arch/mips/configs/bmips_be_defconfig index 24dcb90b0f64..acf7785c4cdb 100644 --- a/arch/mips/configs/bmips_be_defconfig +++ b/arch/mips/configs/bmips_be_defconfig | |||
@@ -36,6 +36,7 @@ CONFIG_DEVTMPFS_MOUNT=y | |||
36 | CONFIG_PRINTK_TIME=y | 36 | CONFIG_PRINTK_TIME=y |
37 | CONFIG_BRCMSTB_GISB_ARB=y | 37 | CONFIG_BRCMSTB_GISB_ARB=y |
38 | CONFIG_MTD=y | 38 | CONFIG_MTD=y |
39 | CONFIG_MTD_BCM63XX_PARTS=y | ||
39 | CONFIG_MTD_CFI=y | 40 | CONFIG_MTD_CFI=y |
40 | CONFIG_MTD_CFI_INTELEXT=y | 41 | CONFIG_MTD_CFI_INTELEXT=y |
41 | CONFIG_MTD_CFI_AMDSTD=y | 42 | CONFIG_MTD_CFI_AMDSTD=y |
diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig index e57058d4ec22..dcac308cec39 100644 --- a/arch/mips/configs/cavium_octeon_defconfig +++ b/arch/mips/configs/cavium_octeon_defconfig | |||
@@ -119,14 +119,16 @@ CONFIG_SPI=y | |||
119 | CONFIG_SPI_OCTEON=y | 119 | CONFIG_SPI_OCTEON=y |
120 | # CONFIG_HWMON is not set | 120 | # CONFIG_HWMON is not set |
121 | CONFIG_WATCHDOG=y | 121 | CONFIG_WATCHDOG=y |
122 | # CONFIG_USB_SUPPORT is not set | 122 | CONFIG_USB=m |
123 | CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y | 123 | CONFIG_USB_EHCI_HCD=m |
124 | CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y | 124 | CONFIG_USB_EHCI_HCD_PLATFORM=m |
125 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | 125 | CONFIG_USB_OHCI_HCD=m |
126 | CONFIG_USB_OHCI_HCD_PLATFORM=m | ||
126 | CONFIG_RTC_CLASS=y | 127 | CONFIG_RTC_CLASS=y |
127 | CONFIG_RTC_DRV_DS1307=y | 128 | CONFIG_RTC_DRV_DS1307=y |
128 | CONFIG_STAGING=y | 129 | CONFIG_STAGING=y |
129 | CONFIG_OCTEON_ETHERNET=y | 130 | CONFIG_OCTEON_ETHERNET=y |
131 | CONFIG_OCTEON_USB=m | ||
130 | # CONFIG_IOMMU_SUPPORT is not set | 132 | # CONFIG_IOMMU_SUPPORT is not set |
131 | CONFIG_EXT4_FS=y | 133 | CONFIG_EXT4_FS=y |
132 | CONFIG_EXT4_FS_POSIX_ACL=y | 134 | CONFIG_EXT4_FS_POSIX_ACL=y |
@@ -152,6 +154,9 @@ CONFIG_SECURITY=y | |||
152 | CONFIG_SECURITY_NETWORK=y | 154 | CONFIG_SECURITY_NETWORK=y |
153 | CONFIG_CRYPTO_CBC=y | 155 | CONFIG_CRYPTO_CBC=y |
154 | CONFIG_CRYPTO_HMAC=y | 156 | CONFIG_CRYPTO_HMAC=y |
155 | CONFIG_CRYPTO_MD5=y | 157 | CONFIG_CRYPTO_MD5_OCTEON=y |
158 | CONFIG_CRYPTO_SHA1_OCTEON=m | ||
159 | CONFIG_CRYPTO_SHA256_OCTEON=m | ||
160 | CONFIG_CRYPTO_SHA512_OCTEON=m | ||
156 | CONFIG_CRYPTO_DES=y | 161 | CONFIG_CRYPTO_DES=y |
157 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 162 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index ebc011c51e5a..2b6cb41d5715 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig | |||
@@ -30,7 +30,6 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m | |||
30 | CONFIG_INET_XFRM_MODE_TUNNEL=m | 30 | CONFIG_INET_XFRM_MODE_TUNNEL=m |
31 | CONFIG_INET_XFRM_MODE_BEET=m | 31 | CONFIG_INET_XFRM_MODE_BEET=m |
32 | CONFIG_TCP_MD5SIG=y | 32 | CONFIG_TCP_MD5SIG=y |
33 | CONFIG_IPV6_PRIVACY=y | ||
34 | CONFIG_IPV6_ROUTER_PREF=y | 33 | CONFIG_IPV6_ROUTER_PREF=y |
35 | CONFIG_IPV6_ROUTE_INFO=y | 34 | CONFIG_IPV6_ROUTE_INFO=y |
36 | CONFIG_INET6_AH=m | 35 | CONFIG_INET6_AH=m |
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 6ba9ce9fcdd5..5d83ff755547 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig | |||
@@ -48,7 +48,6 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m | |||
48 | CONFIG_INET_XFRM_MODE_BEET=m | 48 | CONFIG_INET_XFRM_MODE_BEET=m |
49 | # CONFIG_INET_LRO is not set | 49 | # CONFIG_INET_LRO is not set |
50 | CONFIG_TCP_MD5SIG=y | 50 | CONFIG_TCP_MD5SIG=y |
51 | CONFIG_IPV6_PRIVACY=y | ||
52 | CONFIG_IPV6_ROUTER_PREF=y | 51 | CONFIG_IPV6_ROUTER_PREF=y |
53 | CONFIG_IPV6_ROUTE_INFO=y | 52 | CONFIG_IPV6_ROUTE_INFO=y |
54 | CONFIG_IPV6_OPTIMISTIC_DAD=y | 53 | CONFIG_IPV6_OPTIMISTIC_DAD=y |
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 77e9f505f5e4..2b74aee320a1 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig | |||
@@ -43,7 +43,6 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m | |||
43 | CONFIG_INET_XFRM_MODE_BEET=m | 43 | CONFIG_INET_XFRM_MODE_BEET=m |
44 | CONFIG_TCP_MD5SIG=y | 44 | CONFIG_TCP_MD5SIG=y |
45 | CONFIG_IPV6=y | 45 | CONFIG_IPV6=y |
46 | CONFIG_IPV6_PRIVACY=y | ||
47 | CONFIG_IPV6_ROUTER_PREF=y | 46 | CONFIG_IPV6_ROUTER_PREF=y |
48 | CONFIG_IPV6_ROUTE_INFO=y | 47 | CONFIG_IPV6_ROUTE_INFO=y |
49 | CONFIG_IPV6_OPTIMISTIC_DAD=y | 48 | CONFIG_IPV6_OPTIMISTIC_DAD=y |
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index a5e85e1ee5de..3019fce63cd3 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig | |||
@@ -34,7 +34,6 @@ CONFIG_IP_PIMSM_V2=y | |||
34 | CONFIG_INET_XFRM_MODE_TRANSPORT=m | 34 | CONFIG_INET_XFRM_MODE_TRANSPORT=m |
35 | CONFIG_INET_XFRM_MODE_TUNNEL=m | 35 | CONFIG_INET_XFRM_MODE_TUNNEL=m |
36 | CONFIG_TCP_MD5SIG=y | 36 | CONFIG_TCP_MD5SIG=y |
37 | CONFIG_IPV6_PRIVACY=y | ||
38 | CONFIG_IPV6_ROUTER_PREF=y | 37 | CONFIG_IPV6_ROUTER_PREF=y |
39 | CONFIG_IPV6_ROUTE_INFO=y | 38 | CONFIG_IPV6_ROUTE_INFO=y |
40 | CONFIG_INET6_AH=m | 39 | CONFIG_INET6_AH=m |
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index d1f198b072a0..5da76e0e120f 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig | |||
@@ -71,7 +71,6 @@ CONFIG_TCP_CONG_ADVANCED=y | |||
71 | CONFIG_TCP_CONG_BIC=y | 71 | CONFIG_TCP_CONG_BIC=y |
72 | CONFIG_DEFAULT_BIC=y | 72 | CONFIG_DEFAULT_BIC=y |
73 | CONFIG_TCP_MD5SIG=y | 73 | CONFIG_TCP_MD5SIG=y |
74 | CONFIG_IPV6_PRIVACY=y | ||
75 | CONFIG_IPV6_ROUTER_PREF=y | 74 | CONFIG_IPV6_ROUTER_PREF=y |
76 | CONFIG_IPV6_TUNNEL=m | 75 | CONFIG_IPV6_TUNNEL=m |
77 | CONFIG_IPV6_MULTIPLE_TABLES=y | 76 | CONFIG_IPV6_MULTIPLE_TABLES=y |
diff --git a/arch/mips/configs/ls1b_defconfig b/arch/mips/configs/loongson1b_defconfig index 1b2cc1fb26a1..c442f27685f4 100644 --- a/arch/mips/configs/ls1b_defconfig +++ b/arch/mips/configs/loongson1b_defconfig | |||
@@ -1,19 +1,17 @@ | |||
1 | CONFIG_MACH_LOONGSON32=y | 1 | CONFIG_MACH_LOONGSON32=y |
2 | CONFIG_PREEMPT=y | 2 | CONFIG_PREEMPT=y |
3 | # CONFIG_SECCOMP is not set | 3 | # CONFIG_SECCOMP is not set |
4 | CONFIG_EXPERIMENTAL=y | ||
5 | # CONFIG_LOCALVERSION_AUTO is not set | 4 | # CONFIG_LOCALVERSION_AUTO is not set |
5 | CONFIG_KERNEL_XZ=y | ||
6 | CONFIG_SYSVIPC=y | 6 | CONFIG_SYSVIPC=y |
7 | CONFIG_HIGH_RES_TIMERS=y | ||
7 | CONFIG_BSD_PROCESS_ACCT=y | 8 | CONFIG_BSD_PROCESS_ACCT=y |
8 | CONFIG_BSD_PROCESS_ACCT_V3=y | 9 | CONFIG_BSD_PROCESS_ACCT_V3=y |
9 | CONFIG_HIGH_RES_TIMERS=y | ||
10 | CONFIG_IKCONFIG=y | 10 | CONFIG_IKCONFIG=y |
11 | CONFIG_IKCONFIG_PROC=y | 11 | CONFIG_IKCONFIG_PROC=y |
12 | CONFIG_LOG_BUF_SHIFT=16 | 12 | CONFIG_LOG_BUF_SHIFT=16 |
13 | CONFIG_NAMESPACES=y | 13 | CONFIG_NAMESPACES=y |
14 | CONFIG_BLK_DEV_INITRD=y | 14 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
15 | CONFIG_RD_BZIP2=y | ||
16 | CONFIG_RD_LZMA=y | ||
17 | CONFIG_EXPERT=y | 15 | CONFIG_EXPERT=y |
18 | CONFIG_PERF_EVENTS=y | 16 | CONFIG_PERF_EVENTS=y |
19 | # CONFIG_COMPAT_BRK is not set | 17 | # CONFIG_COMPAT_BRK is not set |
@@ -41,6 +39,12 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
41 | CONFIG_DEVTMPFS=y | 39 | CONFIG_DEVTMPFS=y |
42 | CONFIG_DEVTMPFS_MOUNT=y | 40 | CONFIG_DEVTMPFS_MOUNT=y |
43 | # CONFIG_STANDALONE is not set | 41 | # CONFIG_STANDALONE is not set |
42 | CONFIG_MTD=y | ||
43 | CONFIG_MTD_CMDLINE_PARTS=y | ||
44 | CONFIG_MTD_BLOCK=y | ||
45 | CONFIG_MTD_NAND=y | ||
46 | CONFIG_MTD_NAND_LOONGSON1=y | ||
47 | CONFIG_MTD_UBI=y | ||
44 | CONFIG_BLK_DEV_LOOP=y | 48 | CONFIG_BLK_DEV_LOOP=y |
45 | CONFIG_SCSI=m | 49 | CONFIG_SCSI=m |
46 | # CONFIG_SCSI_PROC_FS is not set | 50 | # CONFIG_SCSI_PROC_FS is not set |
@@ -48,7 +52,6 @@ CONFIG_BLK_DEV_SD=m | |||
48 | # CONFIG_SCSI_LOWLEVEL is not set | 52 | # CONFIG_SCSI_LOWLEVEL is not set |
49 | CONFIG_NETDEVICES=y | 53 | CONFIG_NETDEVICES=y |
50 | # CONFIG_NET_VENDOR_BROADCOM is not set | 54 | # CONFIG_NET_VENDOR_BROADCOM is not set |
51 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
52 | # CONFIG_NET_VENDOR_INTEL is not set | 55 | # CONFIG_NET_VENDOR_INTEL is not set |
53 | # CONFIG_NET_VENDOR_MARVELL is not set | 56 | # CONFIG_NET_VENDOR_MARVELL is not set |
54 | # CONFIG_NET_VENDOR_MICREL is not set | 57 | # CONFIG_NET_VENDOR_MICREL is not set |
@@ -56,7 +59,6 @@ CONFIG_NETDEVICES=y | |||
56 | # CONFIG_NET_VENDOR_SEEQ is not set | 59 | # CONFIG_NET_VENDOR_SEEQ is not set |
57 | # CONFIG_NET_VENDOR_SMSC is not set | 60 | # CONFIG_NET_VENDOR_SMSC is not set |
58 | CONFIG_STMMAC_ETH=y | 61 | CONFIG_STMMAC_ETH=y |
59 | CONFIG_STMMAC_DA=y | ||
60 | # CONFIG_NET_VENDOR_WIZNET is not set | 62 | # CONFIG_NET_VENDOR_WIZNET is not set |
61 | # CONFIG_WLAN is not set | 63 | # CONFIG_WLAN is not set |
62 | CONFIG_INPUT_EVDEV=y | 64 | CONFIG_INPUT_EVDEV=y |
@@ -69,18 +71,25 @@ CONFIG_LEGACY_PTY_COUNT=8 | |||
69 | CONFIG_SERIAL_8250=y | 71 | CONFIG_SERIAL_8250=y |
70 | CONFIG_SERIAL_8250_CONSOLE=y | 72 | CONFIG_SERIAL_8250_CONSOLE=y |
71 | # CONFIG_HW_RANDOM is not set | 73 | # CONFIG_HW_RANDOM is not set |
74 | CONFIG_GPIOLIB=y | ||
75 | CONFIG_GPIO_LOONGSON1=y | ||
72 | # CONFIG_HWMON is not set | 76 | # CONFIG_HWMON is not set |
73 | # CONFIG_VGA_CONSOLE is not set | 77 | # CONFIG_VGA_CONSOLE is not set |
74 | CONFIG_USB_HID=m | ||
75 | CONFIG_HID_GENERIC=m | 78 | CONFIG_HID_GENERIC=m |
79 | CONFIG_USB_HID=m | ||
76 | CONFIG_USB=y | 80 | CONFIG_USB=y |
77 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | 81 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y |
78 | CONFIG_USB_EHCI_HCD=y | 82 | CONFIG_USB_EHCI_HCD=y |
79 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
80 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | 83 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set |
84 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
81 | CONFIG_USB_STORAGE=m | 85 | CONFIG_USB_STORAGE=m |
82 | CONFIG_USB_SERIAL=m | 86 | CONFIG_USB_SERIAL=m |
83 | CONFIG_USB_SERIAL_PL2303=m | 87 | CONFIG_USB_SERIAL_PL2303=m |
88 | CONFIG_NEW_LEDS=y | ||
89 | CONFIG_LEDS_CLASS=y | ||
90 | CONFIG_LEDS_GPIO=y | ||
91 | CONFIG_LEDS_TRIGGERS=y | ||
92 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
84 | CONFIG_RTC_CLASS=y | 93 | CONFIG_RTC_CLASS=y |
85 | CONFIG_RTC_DRV_LOONGSON1=y | 94 | CONFIG_RTC_DRV_LOONGSON1=y |
86 | # CONFIG_IOMMU_SUPPORT is not set | 95 | # CONFIG_IOMMU_SUPPORT is not set |
@@ -96,15 +105,21 @@ CONFIG_VFAT_FS=y | |||
96 | CONFIG_PROC_KCORE=y | 105 | CONFIG_PROC_KCORE=y |
97 | CONFIG_TMPFS=y | 106 | CONFIG_TMPFS=y |
98 | CONFIG_TMPFS_POSIX_ACL=y | 107 | CONFIG_TMPFS_POSIX_ACL=y |
99 | # CONFIG_MISC_FILESYSTEMS is not set | 108 | CONFIG_UBIFS_FS=y |
109 | CONFIG_UBIFS_FS_ADVANCED_COMPR=y | ||
110 | CONFIG_UBIFS_ATIME_SUPPORT=y | ||
100 | CONFIG_NFS_FS=y | 111 | CONFIG_NFS_FS=y |
101 | CONFIG_ROOT_NFS=y | 112 | CONFIG_ROOT_NFS=y |
102 | CONFIG_NLS_CODEPAGE_437=m | 113 | CONFIG_NLS_CODEPAGE_437=m |
103 | CONFIG_NLS_ISO8859_1=m | 114 | CONFIG_NLS_ISO8859_1=m |
115 | CONFIG_DYNAMIC_DEBUG=y | ||
104 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | 116 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
105 | # CONFIG_ENABLE_MUST_CHECK is not set | 117 | # CONFIG_ENABLE_MUST_CHECK is not set |
118 | CONFIG_DEBUG_FS=y | ||
106 | CONFIG_MAGIC_SYSRQ=y | 119 | CONFIG_MAGIC_SYSRQ=y |
107 | # CONFIG_SCHED_DEBUG is not set | 120 | # CONFIG_SCHED_DEBUG is not set |
108 | # CONFIG_DEBUG_PREEMPT is not set | 121 | # CONFIG_DEBUG_PREEMPT is not set |
109 | # CONFIG_FTRACE is not set | 122 | # CONFIG_FTRACE is not set |
110 | # CONFIG_EARLY_PRINTK is not set | 123 | # CONFIG_EARLY_PRINTK is not set |
124 | # CONFIG_CRYPTO_ECHAINIV is not set | ||
125 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 9b6926d6bb32..f3f60056bc27 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig | |||
@@ -51,7 +51,6 @@ CONFIG_INET_IPCOMP=m | |||
51 | CONFIG_INET_XFRM_MODE_TRANSPORT=m | 51 | CONFIG_INET_XFRM_MODE_TRANSPORT=m |
52 | CONFIG_INET_XFRM_MODE_TUNNEL=m | 52 | CONFIG_INET_XFRM_MODE_TUNNEL=m |
53 | CONFIG_INET_XFRM_MODE_BEET=m | 53 | CONFIG_INET_XFRM_MODE_BEET=m |
54 | CONFIG_IPV6_PRIVACY=y | ||
55 | CONFIG_INET6_AH=m | 54 | CONFIG_INET6_AH=m |
56 | CONFIG_INET6_ESP=m | 55 | CONFIG_INET6_ESP=m |
57 | CONFIG_INET6_IPCOMP=m | 56 | CONFIG_INET6_IPCOMP=m |
diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig index b3d1d37f85ea..b496c25fced6 100644 --- a/arch/mips/configs/nlm_xlp_defconfig +++ b/arch/mips/configs/nlm_xlp_defconfig | |||
@@ -95,7 +95,6 @@ CONFIG_TCP_CONG_YEAH=m | |||
95 | CONFIG_TCP_CONG_ILLINOIS=m | 95 | CONFIG_TCP_CONG_ILLINOIS=m |
96 | CONFIG_TCP_MD5SIG=y | 96 | CONFIG_TCP_MD5SIG=y |
97 | CONFIG_IPV6=y | 97 | CONFIG_IPV6=y |
98 | CONFIG_IPV6_PRIVACY=y | ||
99 | CONFIG_INET6_AH=m | 98 | CONFIG_INET6_AH=m |
100 | CONFIG_INET6_ESP=m | 99 | CONFIG_INET6_ESP=m |
101 | CONFIG_INET6_IPCOMP=m | 100 | CONFIG_INET6_IPCOMP=m |
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig index 3d8016d6cf3e..8e99ad807a57 100644 --- a/arch/mips/configs/nlm_xlr_defconfig +++ b/arch/mips/configs/nlm_xlr_defconfig | |||
@@ -75,7 +75,6 @@ CONFIG_TCP_CONG_YEAH=m | |||
75 | CONFIG_TCP_CONG_ILLINOIS=m | 75 | CONFIG_TCP_CONG_ILLINOIS=m |
76 | CONFIG_TCP_MD5SIG=y | 76 | CONFIG_TCP_MD5SIG=y |
77 | CONFIG_IPV6=y | 77 | CONFIG_IPV6=y |
78 | CONFIG_IPV6_PRIVACY=y | ||
79 | CONFIG_INET6_AH=m | 78 | CONFIG_INET6_AH=m |
80 | CONFIG_INET6_ESP=m | 79 | CONFIG_INET6_ESP=m |
81 | CONFIG_INET6_IPCOMP=m | 80 | CONFIG_INET6_IPCOMP=m |
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 82db4e3e4cf1..c2b4e3f33a73 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig | |||
@@ -37,7 +37,6 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m | |||
37 | CONFIG_INET_XFRM_MODE_TUNNEL=m | 37 | CONFIG_INET_XFRM_MODE_TUNNEL=m |
38 | CONFIG_INET_XFRM_MODE_BEET=m | 38 | CONFIG_INET_XFRM_MODE_BEET=m |
39 | CONFIG_TCP_MD5SIG=y | 39 | CONFIG_TCP_MD5SIG=y |
40 | CONFIG_IPV6_PRIVACY=y | ||
41 | CONFIG_IPV6_ROUTER_PREF=y | 40 | CONFIG_IPV6_ROUTER_PREF=y |
42 | CONFIG_IPV6_ROUTE_INFO=y | 41 | CONFIG_IPV6_ROUTE_INFO=y |
43 | CONFIG_INET6_AH=m | 42 | CONFIG_INET6_AH=m |
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index a0b8943c8f11..1c3bf9fe926f 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c | |||
@@ -60,6 +60,7 @@ EXPORT_SYMBOL(dec_kn_slot_size); | |||
60 | int dec_tc_bus; | 60 | int dec_tc_bus; |
61 | 61 | ||
62 | DEFINE_SPINLOCK(ioasic_ssr_lock); | 62 | DEFINE_SPINLOCK(ioasic_ssr_lock); |
63 | EXPORT_SYMBOL(ioasic_ssr_lock); | ||
63 | 64 | ||
64 | volatile u32 *ioasic_base; | 65 | volatile u32 *ioasic_base; |
65 | 66 | ||
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index c7fe4d01e79c..9740066cc631 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild | |||
@@ -1,5 +1,6 @@ | |||
1 | # MIPS headers | 1 | # MIPS headers |
2 | generic-(CONFIG_GENERIC_CSUM) += checksum.h | 2 | generic-(CONFIG_GENERIC_CSUM) += checksum.h |
3 | generic-y += clkdev.h | ||
3 | generic-y += cputime.h | 4 | generic-y += cputime.h |
4 | generic-y += current.h | 5 | generic-y += current.h |
5 | generic-y += dma-contiguous.h | 6 | generic-y += dma-contiguous.h |
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 867f924b05c7..6741673c92ca 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h | |||
@@ -235,6 +235,7 @@ | |||
235 | .macro ld_b wd, off, base | 235 | .macro ld_b wd, off, base |
236 | .set push | 236 | .set push |
237 | .set mips32r2 | 237 | .set mips32r2 |
238 | .set fp=64 | ||
238 | .set msa | 239 | .set msa |
239 | ld.b $w\wd, \off(\base) | 240 | ld.b $w\wd, \off(\base) |
240 | .set pop | 241 | .set pop |
@@ -243,6 +244,7 @@ | |||
243 | .macro ld_h wd, off, base | 244 | .macro ld_h wd, off, base |
244 | .set push | 245 | .set push |
245 | .set mips32r2 | 246 | .set mips32r2 |
247 | .set fp=64 | ||
246 | .set msa | 248 | .set msa |
247 | ld.h $w\wd, \off(\base) | 249 | ld.h $w\wd, \off(\base) |
248 | .set pop | 250 | .set pop |
@@ -251,6 +253,7 @@ | |||
251 | .macro ld_w wd, off, base | 253 | .macro ld_w wd, off, base |
252 | .set push | 254 | .set push |
253 | .set mips32r2 | 255 | .set mips32r2 |
256 | .set fp=64 | ||
254 | .set msa | 257 | .set msa |
255 | ld.w $w\wd, \off(\base) | 258 | ld.w $w\wd, \off(\base) |
256 | .set pop | 259 | .set pop |
@@ -268,6 +271,7 @@ | |||
268 | .macro st_b wd, off, base | 271 | .macro st_b wd, off, base |
269 | .set push | 272 | .set push |
270 | .set mips32r2 | 273 | .set mips32r2 |
274 | .set fp=64 | ||
271 | .set msa | 275 | .set msa |
272 | st.b $w\wd, \off(\base) | 276 | st.b $w\wd, \off(\base) |
273 | .set pop | 277 | .set pop |
@@ -276,6 +280,7 @@ | |||
276 | .macro st_h wd, off, base | 280 | .macro st_h wd, off, base |
277 | .set push | 281 | .set push |
278 | .set mips32r2 | 282 | .set mips32r2 |
283 | .set fp=64 | ||
279 | .set msa | 284 | .set msa |
280 | st.h $w\wd, \off(\base) | 285 | st.h $w\wd, \off(\base) |
281 | .set pop | 286 | .set pop |
@@ -284,6 +289,7 @@ | |||
284 | .macro st_w wd, off, base | 289 | .macro st_w wd, off, base |
285 | .set push | 290 | .set push |
286 | .set mips32r2 | 291 | .set mips32r2 |
292 | .set fp=64 | ||
287 | .set msa | 293 | .set msa |
288 | st.w $w\wd, \off(\base) | 294 | st.w $w\wd, \off(\base) |
289 | .set pop | 295 | .set pop |
@@ -298,21 +304,21 @@ | |||
298 | .set pop | 304 | .set pop |
299 | .endm | 305 | .endm |
300 | 306 | ||
301 | .macro copy_u_w ws, n | 307 | .macro copy_s_w ws, n |
302 | .set push | 308 | .set push |
303 | .set mips32r2 | 309 | .set mips32r2 |
304 | .set fp=64 | 310 | .set fp=64 |
305 | .set msa | 311 | .set msa |
306 | copy_u.w $1, $w\ws[\n] | 312 | copy_s.w $1, $w\ws[\n] |
307 | .set pop | 313 | .set pop |
308 | .endm | 314 | .endm |
309 | 315 | ||
310 | .macro copy_u_d ws, n | 316 | .macro copy_s_d ws, n |
311 | .set push | 317 | .set push |
312 | .set mips64r2 | 318 | .set mips64r2 |
313 | .set fp=64 | 319 | .set fp=64 |
314 | .set msa | 320 | .set msa |
315 | copy_u.d $1, $w\ws[\n] | 321 | copy_s.d $1, $w\ws[\n] |
316 | .set pop | 322 | .set pop |
317 | .endm | 323 | .endm |
318 | 324 | ||
@@ -346,8 +352,8 @@ | |||
346 | #define STH_MSA_INSN 0x5800081f | 352 | #define STH_MSA_INSN 0x5800081f |
347 | #define STW_MSA_INSN 0x5800082f | 353 | #define STW_MSA_INSN 0x5800082f |
348 | #define STD_MSA_INSN 0x5800083f | 354 | #define STD_MSA_INSN 0x5800083f |
349 | #define COPY_UW_MSA_INSN 0x58f00056 | 355 | #define COPY_SW_MSA_INSN 0x58b00056 |
350 | #define COPY_UD_MSA_INSN 0x58f80056 | 356 | #define COPY_SD_MSA_INSN 0x58b80056 |
351 | #define INSERT_W_MSA_INSN 0x59300816 | 357 | #define INSERT_W_MSA_INSN 0x59300816 |
352 | #define INSERT_D_MSA_INSN 0x59380816 | 358 | #define INSERT_D_MSA_INSN 0x59380816 |
353 | #else | 359 | #else |
@@ -361,8 +367,8 @@ | |||
361 | #define STH_MSA_INSN 0x78000825 | 367 | #define STH_MSA_INSN 0x78000825 |
362 | #define STW_MSA_INSN 0x78000826 | 368 | #define STW_MSA_INSN 0x78000826 |
363 | #define STD_MSA_INSN 0x78000827 | 369 | #define STD_MSA_INSN 0x78000827 |
364 | #define COPY_UW_MSA_INSN 0x78f00059 | 370 | #define COPY_SW_MSA_INSN 0x78b00059 |
365 | #define COPY_UD_MSA_INSN 0x78f80059 | 371 | #define COPY_SD_MSA_INSN 0x78b80059 |
366 | #define INSERT_W_MSA_INSN 0x79300819 | 372 | #define INSERT_W_MSA_INSN 0x79300819 |
367 | #define INSERT_D_MSA_INSN 0x79380819 | 373 | #define INSERT_D_MSA_INSN 0x79380819 |
368 | #endif | 374 | #endif |
@@ -393,7 +399,7 @@ | |||
393 | .set push | 399 | .set push |
394 | .set noat | 400 | .set noat |
395 | SET_HARDFLOAT | 401 | SET_HARDFLOAT |
396 | addu $1, \base, \off | 402 | PTR_ADDU $1, \base, \off |
397 | .word LDB_MSA_INSN | (\wd << 6) | 403 | .word LDB_MSA_INSN | (\wd << 6) |
398 | .set pop | 404 | .set pop |
399 | .endm | 405 | .endm |
@@ -402,7 +408,7 @@ | |||
402 | .set push | 408 | .set push |
403 | .set noat | 409 | .set noat |
404 | SET_HARDFLOAT | 410 | SET_HARDFLOAT |
405 | addu $1, \base, \off | 411 | PTR_ADDU $1, \base, \off |
406 | .word LDH_MSA_INSN | (\wd << 6) | 412 | .word LDH_MSA_INSN | (\wd << 6) |
407 | .set pop | 413 | .set pop |
408 | .endm | 414 | .endm |
@@ -411,7 +417,7 @@ | |||
411 | .set push | 417 | .set push |
412 | .set noat | 418 | .set noat |
413 | SET_HARDFLOAT | 419 | SET_HARDFLOAT |
414 | addu $1, \base, \off | 420 | PTR_ADDU $1, \base, \off |
415 | .word LDW_MSA_INSN | (\wd << 6) | 421 | .word LDW_MSA_INSN | (\wd << 6) |
416 | .set pop | 422 | .set pop |
417 | .endm | 423 | .endm |
@@ -420,7 +426,7 @@ | |||
420 | .set push | 426 | .set push |
421 | .set noat | 427 | .set noat |
422 | SET_HARDFLOAT | 428 | SET_HARDFLOAT |
423 | addu $1, \base, \off | 429 | PTR_ADDU $1, \base, \off |
424 | .word LDD_MSA_INSN | (\wd << 6) | 430 | .word LDD_MSA_INSN | (\wd << 6) |
425 | .set pop | 431 | .set pop |
426 | .endm | 432 | .endm |
@@ -429,7 +435,7 @@ | |||
429 | .set push | 435 | .set push |
430 | .set noat | 436 | .set noat |
431 | SET_HARDFLOAT | 437 | SET_HARDFLOAT |
432 | addu $1, \base, \off | 438 | PTR_ADDU $1, \base, \off |
433 | .word STB_MSA_INSN | (\wd << 6) | 439 | .word STB_MSA_INSN | (\wd << 6) |
434 | .set pop | 440 | .set pop |
435 | .endm | 441 | .endm |
@@ -438,7 +444,7 @@ | |||
438 | .set push | 444 | .set push |
439 | .set noat | 445 | .set noat |
440 | SET_HARDFLOAT | 446 | SET_HARDFLOAT |
441 | addu $1, \base, \off | 447 | PTR_ADDU $1, \base, \off |
442 | .word STH_MSA_INSN | (\wd << 6) | 448 | .word STH_MSA_INSN | (\wd << 6) |
443 | .set pop | 449 | .set pop |
444 | .endm | 450 | .endm |
@@ -447,7 +453,7 @@ | |||
447 | .set push | 453 | .set push |
448 | .set noat | 454 | .set noat |
449 | SET_HARDFLOAT | 455 | SET_HARDFLOAT |
450 | addu $1, \base, \off | 456 | PTR_ADDU $1, \base, \off |
451 | .word STW_MSA_INSN | (\wd << 6) | 457 | .word STW_MSA_INSN | (\wd << 6) |
452 | .set pop | 458 | .set pop |
453 | .endm | 459 | .endm |
@@ -456,26 +462,26 @@ | |||
456 | .set push | 462 | .set push |
457 | .set noat | 463 | .set noat |
458 | SET_HARDFLOAT | 464 | SET_HARDFLOAT |
459 | addu $1, \base, \off | 465 | PTR_ADDU $1, \base, \off |
460 | .word STD_MSA_INSN | (\wd << 6) | 466 | .word STD_MSA_INSN | (\wd << 6) |
461 | .set pop | 467 | .set pop |
462 | .endm | 468 | .endm |
463 | 469 | ||
464 | .macro copy_u_w ws, n | 470 | .macro copy_s_w ws, n |
465 | .set push | 471 | .set push |
466 | .set noat | 472 | .set noat |
467 | SET_HARDFLOAT | 473 | SET_HARDFLOAT |
468 | .insn | 474 | .insn |
469 | .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11) | 475 | .word COPY_SW_MSA_INSN | (\n << 16) | (\ws << 11) |
470 | .set pop | 476 | .set pop |
471 | .endm | 477 | .endm |
472 | 478 | ||
473 | .macro copy_u_d ws, n | 479 | .macro copy_s_d ws, n |
474 | .set push | 480 | .set push |
475 | .set noat | 481 | .set noat |
476 | SET_HARDFLOAT | 482 | SET_HARDFLOAT |
477 | .insn | 483 | .insn |
478 | .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11) | 484 | .word COPY_SD_MSA_INSN | (\n << 16) | (\ws << 11) |
479 | .set pop | 485 | .set pop |
480 | .endm | 486 | .endm |
481 | 487 | ||
@@ -496,41 +502,52 @@ | |||
496 | .endm | 502 | .endm |
497 | #endif | 503 | #endif |
498 | 504 | ||
505 | #ifdef TOOLCHAIN_SUPPORTS_MSA | ||
506 | #define FPR_BASE_OFFS THREAD_FPR0 | ||
507 | #define FPR_BASE $1 | ||
508 | #else | ||
509 | #define FPR_BASE_OFFS 0 | ||
510 | #define FPR_BASE \thread | ||
511 | #endif | ||
512 | |||
499 | .macro msa_save_all thread | 513 | .macro msa_save_all thread |
500 | st_d 0, THREAD_FPR0, \thread | ||
501 | st_d 1, THREAD_FPR1, \thread | ||
502 | st_d 2, THREAD_FPR2, \thread | ||
503 | st_d 3, THREAD_FPR3, \thread | ||
504 | st_d 4, THREAD_FPR4, \thread | ||
505 | st_d 5, THREAD_FPR5, \thread | ||
506 | st_d 6, THREAD_FPR6, \thread | ||
507 | st_d 7, THREAD_FPR7, \thread | ||
508 | st_d 8, THREAD_FPR8, \thread | ||
509 | st_d 9, THREAD_FPR9, \thread | ||
510 | st_d 10, THREAD_FPR10, \thread | ||
511 | st_d 11, THREAD_FPR11, \thread | ||
512 | st_d 12, THREAD_FPR12, \thread | ||
513 | st_d 13, THREAD_FPR13, \thread | ||
514 | st_d 14, THREAD_FPR14, \thread | ||
515 | st_d 15, THREAD_FPR15, \thread | ||
516 | st_d 16, THREAD_FPR16, \thread | ||
517 | st_d 17, THREAD_FPR17, \thread | ||
518 | st_d 18, THREAD_FPR18, \thread | ||
519 | st_d 19, THREAD_FPR19, \thread | ||
520 | st_d 20, THREAD_FPR20, \thread | ||
521 | st_d 21, THREAD_FPR21, \thread | ||
522 | st_d 22, THREAD_FPR22, \thread | ||
523 | st_d 23, THREAD_FPR23, \thread | ||
524 | st_d 24, THREAD_FPR24, \thread | ||
525 | st_d 25, THREAD_FPR25, \thread | ||
526 | st_d 26, THREAD_FPR26, \thread | ||
527 | st_d 27, THREAD_FPR27, \thread | ||
528 | st_d 28, THREAD_FPR28, \thread | ||
529 | st_d 29, THREAD_FPR29, \thread | ||
530 | st_d 30, THREAD_FPR30, \thread | ||
531 | st_d 31, THREAD_FPR31, \thread | ||
532 | .set push | 514 | .set push |
533 | .set noat | 515 | .set noat |
516 | #ifdef TOOLCHAIN_SUPPORTS_MSA | ||
517 | PTR_ADDU FPR_BASE, \thread, FPR_BASE_OFFS | ||
518 | #endif | ||
519 | st_d 0, THREAD_FPR0 - FPR_BASE_OFFS, FPR_BASE | ||
520 | st_d 1, THREAD_FPR1 - FPR_BASE_OFFS, FPR_BASE | ||
521 | st_d 2, THREAD_FPR2 - FPR_BASE_OFFS, FPR_BASE | ||
522 | st_d 3, THREAD_FPR3 - FPR_BASE_OFFS, FPR_BASE | ||
523 | st_d 4, THREAD_FPR4 - FPR_BASE_OFFS, FPR_BASE | ||
524 | st_d 5, THREAD_FPR5 - FPR_BASE_OFFS, FPR_BASE | ||
525 | st_d 6, THREAD_FPR6 - FPR_BASE_OFFS, FPR_BASE | ||
526 | st_d 7, THREAD_FPR7 - FPR_BASE_OFFS, FPR_BASE | ||
527 | st_d 8, THREAD_FPR8 - FPR_BASE_OFFS, FPR_BASE | ||
528 | st_d 9, THREAD_FPR9 - FPR_BASE_OFFS, FPR_BASE | ||
529 | st_d 10, THREAD_FPR10 - FPR_BASE_OFFS, FPR_BASE | ||
530 | st_d 11, THREAD_FPR11 - FPR_BASE_OFFS, FPR_BASE | ||
531 | st_d 12, THREAD_FPR12 - FPR_BASE_OFFS, FPR_BASE | ||
532 | st_d 13, THREAD_FPR13 - FPR_BASE_OFFS, FPR_BASE | ||
533 | st_d 14, THREAD_FPR14 - FPR_BASE_OFFS, FPR_BASE | ||
534 | st_d 15, THREAD_FPR15 - FPR_BASE_OFFS, FPR_BASE | ||
535 | st_d 16, THREAD_FPR16 - FPR_BASE_OFFS, FPR_BASE | ||
536 | st_d 17, THREAD_FPR17 - FPR_BASE_OFFS, FPR_BASE | ||
537 | st_d 18, THREAD_FPR18 - FPR_BASE_OFFS, FPR_BASE | ||
538 | st_d 19, THREAD_FPR19 - FPR_BASE_OFFS, FPR_BASE | ||
539 | st_d 20, THREAD_FPR20 - FPR_BASE_OFFS, FPR_BASE | ||
540 | st_d 21, THREAD_FPR21 - FPR_BASE_OFFS, FPR_BASE | ||
541 | st_d 22, THREAD_FPR22 - FPR_BASE_OFFS, FPR_BASE | ||
542 | st_d 23, THREAD_FPR23 - FPR_BASE_OFFS, FPR_BASE | ||
543 | st_d 24, THREAD_FPR24 - FPR_BASE_OFFS, FPR_BASE | ||
544 | st_d 25, THREAD_FPR25 - FPR_BASE_OFFS, FPR_BASE | ||
545 | st_d 26, THREAD_FPR26 - FPR_BASE_OFFS, FPR_BASE | ||
546 | st_d 27, THREAD_FPR27 - FPR_BASE_OFFS, FPR_BASE | ||
547 | st_d 28, THREAD_FPR28 - FPR_BASE_OFFS, FPR_BASE | ||
548 | st_d 29, THREAD_FPR29 - FPR_BASE_OFFS, FPR_BASE | ||
549 | st_d 30, THREAD_FPR30 - FPR_BASE_OFFS, FPR_BASE | ||
550 | st_d 31, THREAD_FPR31 - FPR_BASE_OFFS, FPR_BASE | ||
534 | SET_HARDFLOAT | 551 | SET_HARDFLOAT |
535 | _cfcmsa $1, MSA_CSR | 552 | _cfcmsa $1, MSA_CSR |
536 | sw $1, THREAD_MSA_CSR(\thread) | 553 | sw $1, THREAD_MSA_CSR(\thread) |
@@ -543,40 +560,46 @@ | |||
543 | SET_HARDFLOAT | 560 | SET_HARDFLOAT |
544 | lw $1, THREAD_MSA_CSR(\thread) | 561 | lw $1, THREAD_MSA_CSR(\thread) |
545 | _ctcmsa MSA_CSR, $1 | 562 | _ctcmsa MSA_CSR, $1 |
546 | .set pop | 563 | #ifdef TOOLCHAIN_SUPPORTS_MSA |
547 | ld_d 0, THREAD_FPR0, \thread | 564 | PTR_ADDU FPR_BASE, \thread, FPR_BASE_OFFS |
548 | ld_d 1, THREAD_FPR1, \thread | 565 | #endif |
549 | ld_d 2, THREAD_FPR2, \thread | 566 | ld_d 0, THREAD_FPR0 - FPR_BASE_OFFS, FPR_BASE |
550 | ld_d 3, THREAD_FPR3, \thread | 567 | ld_d 1, THREAD_FPR1 - FPR_BASE_OFFS, FPR_BASE |
551 | ld_d 4, THREAD_FPR4, \thread | 568 | ld_d 2, THREAD_FPR2 - FPR_BASE_OFFS, FPR_BASE |
552 | ld_d 5, THREAD_FPR5, \thread | 569 | ld_d 3, THREAD_FPR3 - FPR_BASE_OFFS, FPR_BASE |
553 | ld_d 6, THREAD_FPR6, \thread | 570 | ld_d 4, THREAD_FPR4 - FPR_BASE_OFFS, FPR_BASE |
554 | ld_d 7, THREAD_FPR7, \thread | 571 | ld_d 5, THREAD_FPR5 - FPR_BASE_OFFS, FPR_BASE |
555 | ld_d 8, THREAD_FPR8, \thread | 572 | ld_d 6, THREAD_FPR6 - FPR_BASE_OFFS, FPR_BASE |
556 | ld_d 9, THREAD_FPR9, \thread | 573 | ld_d 7, THREAD_FPR7 - FPR_BASE_OFFS, FPR_BASE |
557 | ld_d 10, THREAD_FPR10, \thread | 574 | ld_d 8, THREAD_FPR8 - FPR_BASE_OFFS, FPR_BASE |
558 | ld_d 11, THREAD_FPR11, \thread | 575 | ld_d 9, THREAD_FPR9 - FPR_BASE_OFFS, FPR_BASE |
559 | ld_d 12, THREAD_FPR12, \thread | 576 | ld_d 10, THREAD_FPR10 - FPR_BASE_OFFS, FPR_BASE |
560 | ld_d 13, THREAD_FPR13, \thread | 577 | ld_d 11, THREAD_FPR11 - FPR_BASE_OFFS, FPR_BASE |
561 | ld_d 14, THREAD_FPR14, \thread | 578 | ld_d 12, THREAD_FPR12 - FPR_BASE_OFFS, FPR_BASE |
562 | ld_d 15, THREAD_FPR15, \thread | 579 | ld_d 13, THREAD_FPR13 - FPR_BASE_OFFS, FPR_BASE |
563 | ld_d 16, THREAD_FPR16, \thread | 580 | ld_d 14, THREAD_FPR14 - FPR_BASE_OFFS, FPR_BASE |
564 | ld_d 17, THREAD_FPR17, \thread | 581 | ld_d 15, THREAD_FPR15 - FPR_BASE_OFFS, FPR_BASE |
565 | ld_d 18, THREAD_FPR18, \thread | 582 | ld_d 16, THREAD_FPR16 - FPR_BASE_OFFS, FPR_BASE |
566 | ld_d 19, THREAD_FPR19, \thread | 583 | ld_d 17, THREAD_FPR17 - FPR_BASE_OFFS, FPR_BASE |
567 | ld_d 20, THREAD_FPR20, \thread | 584 | ld_d 18, THREAD_FPR18 - FPR_BASE_OFFS, FPR_BASE |
568 | ld_d 21, THREAD_FPR21, \thread | 585 | ld_d 19, THREAD_FPR19 - FPR_BASE_OFFS, FPR_BASE |
569 | ld_d 22, THREAD_FPR22, \thread | 586 | ld_d 20, THREAD_FPR20 - FPR_BASE_OFFS, FPR_BASE |
570 | ld_d 23, THREAD_FPR23, \thread | 587 | ld_d 21, THREAD_FPR21 - FPR_BASE_OFFS, FPR_BASE |
571 | ld_d 24, THREAD_FPR24, \thread | 588 | ld_d 22, THREAD_FPR22 - FPR_BASE_OFFS, FPR_BASE |
572 | ld_d 25, THREAD_FPR25, \thread | 589 | ld_d 23, THREAD_FPR23 - FPR_BASE_OFFS, FPR_BASE |
573 | ld_d 26, THREAD_FPR26, \thread | 590 | ld_d 24, THREAD_FPR24 - FPR_BASE_OFFS, FPR_BASE |
574 | ld_d 27, THREAD_FPR27, \thread | 591 | ld_d 25, THREAD_FPR25 - FPR_BASE_OFFS, FPR_BASE |
575 | ld_d 28, THREAD_FPR28, \thread | 592 | ld_d 26, THREAD_FPR26 - FPR_BASE_OFFS, FPR_BASE |
576 | ld_d 29, THREAD_FPR29, \thread | 593 | ld_d 27, THREAD_FPR27 - FPR_BASE_OFFS, FPR_BASE |
577 | ld_d 30, THREAD_FPR30, \thread | 594 | ld_d 28, THREAD_FPR28 - FPR_BASE_OFFS, FPR_BASE |
578 | ld_d 31, THREAD_FPR31, \thread | 595 | ld_d 29, THREAD_FPR29 - FPR_BASE_OFFS, FPR_BASE |
579 | .endm | 596 | ld_d 30, THREAD_FPR30 - FPR_BASE_OFFS, FPR_BASE |
597 | ld_d 31, THREAD_FPR31 - FPR_BASE_OFFS, FPR_BASE | ||
598 | .set pop | ||
599 | .endm | ||
600 | |||
601 | #undef FPR_BASE_OFFS | ||
602 | #undef FPR_BASE | ||
580 | 603 | ||
581 | .macro msa_init_upper wd | 604 | .macro msa_init_upper wd |
582 | #ifdef CONFIG_64BIT | 605 | #ifdef CONFIG_64BIT |
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index ce9666cf1499..fa57cef12a46 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h | |||
@@ -19,25 +19,10 @@ | |||
19 | #include <asm/byteorder.h> /* sigh ... */ | 19 | #include <asm/byteorder.h> /* sigh ... */ |
20 | #include <asm/compiler.h> | 20 | #include <asm/compiler.h> |
21 | #include <asm/cpu-features.h> | 21 | #include <asm/cpu-features.h> |
22 | #include <asm/llsc.h> | ||
22 | #include <asm/sgidefs.h> | 23 | #include <asm/sgidefs.h> |
23 | #include <asm/war.h> | 24 | #include <asm/war.h> |
24 | 25 | ||
25 | #if _MIPS_SZLONG == 32 | ||
26 | #define SZLONG_LOG 5 | ||
27 | #define SZLONG_MASK 31UL | ||
28 | #define __LL "ll " | ||
29 | #define __SC "sc " | ||
30 | #define __INS "ins " | ||
31 | #define __EXT "ext " | ||
32 | #elif _MIPS_SZLONG == 64 | ||
33 | #define SZLONG_LOG 6 | ||
34 | #define SZLONG_MASK 63UL | ||
35 | #define __LL "lld " | ||
36 | #define __SC "scd " | ||
37 | #define __INS "dins " | ||
38 | #define __EXT "dext " | ||
39 | #endif | ||
40 | |||
41 | /* | 26 | /* |
42 | * These are the "slower" versions of the functions and are in bitops.c. | 27 | * These are the "slower" versions of the functions and are in bitops.c. |
43 | * These functions call raw_local_irq_{save,restore}(). | 28 | * These functions call raw_local_irq_{save,restore}(). |
diff --git a/arch/mips/include/asm/bitrev.h b/arch/mips/include/asm/bitrev.h new file mode 100644 index 000000000000..bc739a404ae3 --- /dev/null +++ b/arch/mips/include/asm/bitrev.h | |||
@@ -0,0 +1,30 @@ | |||
1 | #ifndef __MIPS_ASM_BITREV_H__ | ||
2 | #define __MIPS_ASM_BITREV_H__ | ||
3 | |||
4 | #include <linux/swab.h> | ||
5 | |||
6 | static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x) | ||
7 | { | ||
8 | u32 ret; | ||
9 | |||
10 | asm("bitswap %0, %1" : "=r"(ret) : "r"(__swab32(x))); | ||
11 | return ret; | ||
12 | } | ||
13 | |||
14 | static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x) | ||
15 | { | ||
16 | u16 ret; | ||
17 | |||
18 | asm("bitswap %0, %1" : "=r"(ret) : "r"(__swab16(x))); | ||
19 | return ret; | ||
20 | } | ||
21 | |||
22 | static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x) | ||
23 | { | ||
24 | u8 ret; | ||
25 | |||
26 | asm("bitswap %0, %1" : "=r"(ret) : "r"(x)); | ||
27 | return ret; | ||
28 | } | ||
29 | |||
30 | #endif /* __MIPS_ASM_BITREV_H__ */ | ||
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index 6d25ad33ec78..a92aee7b977a 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h | |||
@@ -88,6 +88,7 @@ extern unsigned long bmips_tp1_irqs; | |||
88 | 88 | ||
89 | extern void bmips_ebase_setup(void); | 89 | extern void bmips_ebase_setup(void); |
90 | extern asmlinkage void plat_wired_tlb_setup(void); | 90 | extern asmlinkage void plat_wired_tlb_setup(void); |
91 | extern void bmips_cpu_setup(void); | ||
91 | 92 | ||
92 | static inline unsigned long bmips_read_zscm_reg(unsigned int offset) | 93 | static inline unsigned long bmips_read_zscm_reg(unsigned int offset) |
93 | { | 94 | { |
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index b603804caac5..9f67033961a6 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h | |||
@@ -144,4 +144,22 @@ static inline void plat_swiotlb_setup(void) {} | |||
144 | 144 | ||
145 | #endif /* CONFIG_SWIOTLB */ | 145 | #endif /* CONFIG_SWIOTLB */ |
146 | 146 | ||
147 | #ifdef CONFIG_USE_OF | ||
148 | /** | ||
149 | * plat_get_fdt() - Return a pointer to the platform's device tree blob | ||
150 | * | ||
151 | * This function provides a platform independent API to get a pointer to the | ||
152 | * flattened device tree blob. The interface between bootloader and kernel | ||
153 | * is not consistent across platforms so it is necessary to provide this | ||
154 | * API such that common startup code can locate the FDT. | ||
155 | * | ||
156 | * This is used by the KASLR code to get command line arguments and random | ||
157 | * seed from the device tree. Any platform wishing to use KASLR should | ||
158 | * provide this API and select SYS_SUPPORTS_RELOCATABLE. | ||
159 | * | ||
160 | * Return: Pointer to the flattened device tree blob. | ||
161 | */ | ||
162 | extern void *plat_get_fdt(void); | ||
163 | #endif /* CONFIG_USE_OF */ | ||
164 | |||
147 | #endif /* _ASM_BOOTINFO_H */ | 165 | #endif /* _ASM_BOOTINFO_H */ |
diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h index 723229f4cf27..34ed22ec6c33 100644 --- a/arch/mips/include/asm/cacheflush.h +++ b/arch/mips/include/asm/cacheflush.h | |||
@@ -51,7 +51,6 @@ extern void (*flush_cache_range)(struct vm_area_struct *vma, | |||
51 | unsigned long start, unsigned long end); | 51 | unsigned long start, unsigned long end); |
52 | extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); | 52 | extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); |
53 | extern void __flush_dcache_page(struct page *page); | 53 | extern void __flush_dcache_page(struct page *page); |
54 | extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page); | ||
55 | 54 | ||
56 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | 55 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
57 | static inline void flush_dcache_page(struct page *page) | 56 | static inline void flush_dcache_page(struct page *page) |
@@ -77,11 +76,6 @@ static inline void flush_anon_page(struct vm_area_struct *vma, | |||
77 | static inline void flush_icache_page(struct vm_area_struct *vma, | 76 | static inline void flush_icache_page(struct vm_area_struct *vma, |
78 | struct page *page) | 77 | struct page *page) |
79 | { | 78 | { |
80 | if (!cpu_has_ic_fills_f_dc && (vma->vm_flags & VM_EXEC) && | ||
81 | Page_dcache_dirty(page)) { | ||
82 | __flush_icache_page(vma, page); | ||
83 | ClearPageDcacheDirty(page); | ||
84 | } | ||
85 | } | 79 | } |
86 | 80 | ||
87 | extern void (*flush_icache_range)(unsigned long start, unsigned long end); | 81 | extern void (*flush_icache_range)(unsigned long start, unsigned long end); |
@@ -132,6 +126,7 @@ static inline void kunmap_noncoherent(void) | |||
132 | static inline void flush_kernel_dcache_page(struct page *page) | 126 | static inline void flush_kernel_dcache_page(struct page *page) |
133 | { | 127 | { |
134 | BUG_ON(cpu_has_dc_aliases && PageHighMem(page)); | 128 | BUG_ON(cpu_has_dc_aliases && PageHighMem(page)); |
129 | flush_dcache_page(page); | ||
135 | } | 130 | } |
136 | 131 | ||
137 | /* | 132 | /* |
diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index c3212ff26723..8031fbc6b69a 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define Cache_I 0x00 | 21 | #define Cache_I 0x00 |
22 | #define Cache_D 0x01 | 22 | #define Cache_D 0x01 |
23 | #define Cache_T 0x02 | 23 | #define Cache_T 0x02 |
24 | #define Cache_V 0x02 /* Loongson-3 */ | ||
24 | #define Cache_S 0x03 | 25 | #define Cache_S 0x03 |
25 | 26 | ||
26 | #define Index_Writeback_Inv 0x00 | 27 | #define Index_Writeback_Inv 0x00 |
@@ -107,4 +108,9 @@ | |||
107 | */ | 108 | */ |
108 | #define Hit_Invalidate_I_Loongson2 (Cache_I | 0x00) | 109 | #define Hit_Invalidate_I_Loongson2 (Cache_I | 0x00) |
109 | 110 | ||
111 | /* | ||
112 | * Loongson3-specific cacheops | ||
113 | */ | ||
114 | #define Index_Writeback_Inv_V (Cache_V | Index_Writeback_Inv) | ||
115 | |||
110 | #endif /* __ASM_CACHEOPS_H */ | 116 | #endif /* __ASM_CACHEOPS_H */ |
diff --git a/arch/mips/include/asm/clkdev.h b/arch/mips/include/asm/clkdev.h deleted file mode 100644 index 1b3ad7b09dc1..000000000000 --- a/arch/mips/include/asm/clkdev.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | * based on arch/arm/include/asm/clkdev.h | ||
3 | * | ||
4 | * Copyright (C) 2008 Russell King. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * Helper for the clk API to assist looking up a struct clk. | ||
11 | */ | ||
12 | #ifndef __ASM_CLKDEV_H | ||
13 | #define __ASM_CLKDEV_H | ||
14 | |||
15 | #include <linux/slab.h> | ||
16 | |||
17 | #ifndef CONFIG_COMMON_CLK | ||
18 | #define __clk_get(clk) ({ 1; }) | ||
19 | #define __clk_put(clk) do { } while (0) | ||
20 | #endif | ||
21 | |||
22 | static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) | ||
23 | { | ||
24 | return kzalloc(size, GFP_KERNEL); | ||
25 | } | ||
26 | |||
27 | #endif | ||
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index eeec8c8e2da2..e6f19fc61bf2 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
@@ -35,6 +35,9 @@ | |||
35 | #ifndef cpu_has_htw | 35 | #ifndef cpu_has_htw |
36 | #define cpu_has_htw (cpu_data[0].options & MIPS_CPU_HTW) | 36 | #define cpu_has_htw (cpu_data[0].options & MIPS_CPU_HTW) |
37 | #endif | 37 | #endif |
38 | #ifndef cpu_has_ldpte | ||
39 | #define cpu_has_ldpte (cpu_data[0].options & MIPS_CPU_LDPTE) | ||
40 | #endif | ||
38 | #ifndef cpu_has_rixiex | 41 | #ifndef cpu_has_rixiex |
39 | #define cpu_has_rixiex (cpu_data[0].options & MIPS_CPU_RIXIEX) | 42 | #define cpu_has_rixiex (cpu_data[0].options & MIPS_CPU_RIXIEX) |
40 | #endif | 43 | #endif |
@@ -117,6 +120,21 @@ | |||
117 | #ifndef kernel_uses_llsc | 120 | #ifndef kernel_uses_llsc |
118 | #define kernel_uses_llsc cpu_has_llsc | 121 | #define kernel_uses_llsc cpu_has_llsc |
119 | #endif | 122 | #endif |
123 | #ifndef cpu_has_guestctl0ext | ||
124 | #define cpu_has_guestctl0ext (cpu_data[0].options & MIPS_CPU_GUESTCTL0EXT) | ||
125 | #endif | ||
126 | #ifndef cpu_has_guestctl1 | ||
127 | #define cpu_has_guestctl1 (cpu_data[0].options & MIPS_CPU_GUESTCTL1) | ||
128 | #endif | ||
129 | #ifndef cpu_has_guestctl2 | ||
130 | #define cpu_has_guestctl2 (cpu_data[0].options & MIPS_CPU_GUESTCTL2) | ||
131 | #endif | ||
132 | #ifndef cpu_has_guestid | ||
133 | #define cpu_has_guestid (cpu_data[0].options & MIPS_CPU_GUESTID) | ||
134 | #endif | ||
135 | #ifndef cpu_has_drg | ||
136 | #define cpu_has_drg (cpu_data[0].options & MIPS_CPU_DRG) | ||
137 | #endif | ||
120 | #ifndef cpu_has_mips16 | 138 | #ifndef cpu_has_mips16 |
121 | #define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16) | 139 | #define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16) |
122 | #endif | 140 | #endif |
@@ -142,8 +160,14 @@ | |||
142 | # endif | 160 | # endif |
143 | #endif | 161 | #endif |
144 | 162 | ||
163 | #ifndef cpu_has_lpa | ||
164 | #define cpu_has_lpa (cpu_data[0].options & MIPS_CPU_LPA) | ||
165 | #endif | ||
166 | #ifndef cpu_has_mvh | ||
167 | #define cpu_has_mvh (cpu_data[0].options & MIPS_CPU_MVH) | ||
168 | #endif | ||
145 | #ifndef cpu_has_xpa | 169 | #ifndef cpu_has_xpa |
146 | #define cpu_has_xpa (cpu_data[0].options & MIPS_CPU_XPA) | 170 | #define cpu_has_xpa (cpu_has_lpa && cpu_has_mvh) |
147 | #endif | 171 | #endif |
148 | #ifndef cpu_has_vtag_icache | 172 | #ifndef cpu_has_vtag_icache |
149 | #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) | 173 | #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) |
@@ -307,10 +331,18 @@ | |||
307 | #define cpu_has_dsp2 (cpu_data[0].ases & MIPS_ASE_DSP2P) | 331 | #define cpu_has_dsp2 (cpu_data[0].ases & MIPS_ASE_DSP2P) |
308 | #endif | 332 | #endif |
309 | 333 | ||
334 | #ifndef cpu_has_dsp3 | ||
335 | #define cpu_has_dsp3 (cpu_data[0].ases & MIPS_ASE_DSP3) | ||
336 | #endif | ||
337 | |||
310 | #ifndef cpu_has_mipsmt | 338 | #ifndef cpu_has_mipsmt |
311 | #define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT) | 339 | #define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT) |
312 | #endif | 340 | #endif |
313 | 341 | ||
342 | #ifndef cpu_has_vp | ||
343 | #define cpu_has_vp (cpu_data[0].options & MIPS_CPU_VP) | ||
344 | #endif | ||
345 | |||
314 | #ifndef cpu_has_userlocal | 346 | #ifndef cpu_has_userlocal |
315 | #define cpu_has_userlocal (cpu_data[0].options & MIPS_CPU_ULRI) | 347 | #define cpu_has_userlocal (cpu_data[0].options & MIPS_CPU_ULRI) |
316 | #endif | 348 | #endif |
@@ -421,4 +453,107 @@ | |||
421 | #define cpu_has_nan_2008 (cpu_data[0].options & MIPS_CPU_NAN_2008) | 453 | #define cpu_has_nan_2008 (cpu_data[0].options & MIPS_CPU_NAN_2008) |
422 | #endif | 454 | #endif |
423 | 455 | ||
456 | #ifndef cpu_has_ebase_wg | ||
457 | # define cpu_has_ebase_wg (cpu_data[0].options & MIPS_CPU_EBASE_WG) | ||
458 | #endif | ||
459 | |||
460 | #ifndef cpu_has_badinstr | ||
461 | # define cpu_has_badinstr (cpu_data[0].options & MIPS_CPU_BADINSTR) | ||
462 | #endif | ||
463 | |||
464 | #ifndef cpu_has_badinstrp | ||
465 | # define cpu_has_badinstrp (cpu_data[0].options & MIPS_CPU_BADINSTRP) | ||
466 | #endif | ||
467 | |||
468 | #ifndef cpu_has_contextconfig | ||
469 | # define cpu_has_contextconfig (cpu_data[0].options & MIPS_CPU_CTXTC) | ||
470 | #endif | ||
471 | |||
472 | #ifndef cpu_has_perf | ||
473 | # define cpu_has_perf (cpu_data[0].options & MIPS_CPU_PERF) | ||
474 | #endif | ||
475 | |||
476 | /* | ||
477 | * Guest capabilities | ||
478 | */ | ||
479 | #ifndef cpu_guest_has_conf1 | ||
480 | #define cpu_guest_has_conf1 (cpu_data[0].guest.conf & (1 << 1)) | ||
481 | #endif | ||
482 | #ifndef cpu_guest_has_conf2 | ||
483 | #define cpu_guest_has_conf2 (cpu_data[0].guest.conf & (1 << 2)) | ||
484 | #endif | ||
485 | #ifndef cpu_guest_has_conf3 | ||
486 | #define cpu_guest_has_conf3 (cpu_data[0].guest.conf & (1 << 3)) | ||
487 | #endif | ||
488 | #ifndef cpu_guest_has_conf4 | ||
489 | #define cpu_guest_has_conf4 (cpu_data[0].guest.conf & (1 << 4)) | ||
490 | #endif | ||
491 | #ifndef cpu_guest_has_conf5 | ||
492 | #define cpu_guest_has_conf5 (cpu_data[0].guest.conf & (1 << 5)) | ||
493 | #endif | ||
494 | #ifndef cpu_guest_has_conf6 | ||
495 | #define cpu_guest_has_conf6 (cpu_data[0].guest.conf & (1 << 6)) | ||
496 | #endif | ||
497 | #ifndef cpu_guest_has_conf7 | ||
498 | #define cpu_guest_has_conf7 (cpu_data[0].guest.conf & (1 << 7)) | ||
499 | #endif | ||
500 | #ifndef cpu_guest_has_fpu | ||
501 | #define cpu_guest_has_fpu (cpu_data[0].guest.options & MIPS_CPU_FPU) | ||
502 | #endif | ||
503 | #ifndef cpu_guest_has_watch | ||
504 | #define cpu_guest_has_watch (cpu_data[0].guest.options & MIPS_CPU_WATCH) | ||
505 | #endif | ||
506 | #ifndef cpu_guest_has_contextconfig | ||
507 | #define cpu_guest_has_contextconfig (cpu_data[0].guest.options & MIPS_CPU_CTXTC) | ||
508 | #endif | ||
509 | #ifndef cpu_guest_has_segments | ||
510 | #define cpu_guest_has_segments (cpu_data[0].guest.options & MIPS_CPU_SEGMENTS) | ||
511 | #endif | ||
512 | #ifndef cpu_guest_has_badinstr | ||
513 | #define cpu_guest_has_badinstr (cpu_data[0].guest.options & MIPS_CPU_BADINSTR) | ||
514 | #endif | ||
515 | #ifndef cpu_guest_has_badinstrp | ||
516 | #define cpu_guest_has_badinstrp (cpu_data[0].guest.options & MIPS_CPU_BADINSTRP) | ||
517 | #endif | ||
518 | #ifndef cpu_guest_has_htw | ||
519 | #define cpu_guest_has_htw (cpu_data[0].guest.options & MIPS_CPU_HTW) | ||
520 | #endif | ||
521 | #ifndef cpu_guest_has_msa | ||
522 | #define cpu_guest_has_msa (cpu_data[0].guest.ases & MIPS_ASE_MSA) | ||
523 | #endif | ||
524 | #ifndef cpu_guest_has_kscr | ||
525 | #define cpu_guest_has_kscr(n) (cpu_data[0].guest.kscratch_mask & (1u << (n))) | ||
526 | #endif | ||
527 | #ifndef cpu_guest_has_rw_llb | ||
528 | #define cpu_guest_has_rw_llb (cpu_has_mips_r6 || (cpu_data[0].guest.options & MIPS_CPU_RW_LLB)) | ||
529 | #endif | ||
530 | #ifndef cpu_guest_has_perf | ||
531 | #define cpu_guest_has_perf (cpu_data[0].guest.options & MIPS_CPU_PERF) | ||
532 | #endif | ||
533 | #ifndef cpu_guest_has_maar | ||
534 | #define cpu_guest_has_maar (cpu_data[0].guest.options & MIPS_CPU_MAAR) | ||
535 | #endif | ||
536 | |||
537 | /* | ||
538 | * Guest dynamic capabilities | ||
539 | */ | ||
540 | #ifndef cpu_guest_has_dyn_fpu | ||
541 | #define cpu_guest_has_dyn_fpu (cpu_data[0].guest.options_dyn & MIPS_CPU_FPU) | ||
542 | #endif | ||
543 | #ifndef cpu_guest_has_dyn_watch | ||
544 | #define cpu_guest_has_dyn_watch (cpu_data[0].guest.options_dyn & MIPS_CPU_WATCH) | ||
545 | #endif | ||
546 | #ifndef cpu_guest_has_dyn_contextconfig | ||
547 | #define cpu_guest_has_dyn_contextconfig (cpu_data[0].guest.options_dyn & MIPS_CPU_CTXTC) | ||
548 | #endif | ||
549 | #ifndef cpu_guest_has_dyn_perf | ||
550 | #define cpu_guest_has_dyn_perf (cpu_data[0].guest.options_dyn & MIPS_CPU_PERF) | ||
551 | #endif | ||
552 | #ifndef cpu_guest_has_dyn_msa | ||
553 | #define cpu_guest_has_dyn_msa (cpu_data[0].guest.ases_dyn & MIPS_ASE_MSA) | ||
554 | #endif | ||
555 | #ifndef cpu_guest_has_dyn_maar | ||
556 | #define cpu_guest_has_dyn_maar (cpu_data[0].guest.options_dyn & MIPS_CPU_MAAR) | ||
557 | #endif | ||
558 | |||
424 | #endif /* __ASM_CPU_FEATURES_H */ | 559 | #endif /* __ASM_CPU_FEATURES_H */ |
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index af12c1f9f1a8..edbe2734a1bf 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h | |||
@@ -28,6 +28,15 @@ struct cache_desc { | |||
28 | unsigned char flags; /* Flags describing cache properties */ | 28 | unsigned char flags; /* Flags describing cache properties */ |
29 | }; | 29 | }; |
30 | 30 | ||
31 | struct guest_info { | ||
32 | unsigned long ases; | ||
33 | unsigned long ases_dyn; | ||
34 | unsigned long long options; | ||
35 | unsigned long long options_dyn; | ||
36 | u8 conf; | ||
37 | u8 kscratch_mask; | ||
38 | }; | ||
39 | |||
31 | /* | 40 | /* |
32 | * Flag definitions | 41 | * Flag definitions |
33 | */ | 42 | */ |
@@ -40,6 +49,9 @@ struct cache_desc { | |||
40 | 49 | ||
41 | struct cpuinfo_mips { | 50 | struct cpuinfo_mips { |
42 | unsigned long asid_cache; | 51 | unsigned long asid_cache; |
52 | #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE | ||
53 | unsigned long asid_mask; | ||
54 | #endif | ||
43 | 55 | ||
44 | /* | 56 | /* |
45 | * Capability and feature descriptor structure for MIPS CPU | 57 | * Capability and feature descriptor structure for MIPS CPU |
@@ -60,6 +72,7 @@ struct cpuinfo_mips { | |||
60 | int tlbsizeftlbways; | 72 | int tlbsizeftlbways; |
61 | struct cache_desc icache; /* Primary I-cache */ | 73 | struct cache_desc icache; /* Primary I-cache */ |
62 | struct cache_desc dcache; /* Primary D or combined I/D cache */ | 74 | struct cache_desc dcache; /* Primary D or combined I/D cache */ |
75 | struct cache_desc vcache; /* Victim cache, between pcache and scache */ | ||
63 | struct cache_desc scache; /* Secondary cache */ | 76 | struct cache_desc scache; /* Secondary cache */ |
64 | struct cache_desc tcache; /* Tertiary/split secondary cache */ | 77 | struct cache_desc tcache; /* Tertiary/split secondary cache */ |
65 | int srsets; /* Shadow register sets */ | 78 | int srsets; /* Shadow register sets */ |
@@ -68,7 +81,7 @@ struct cpuinfo_mips { | |||
68 | #ifdef CONFIG_64BIT | 81 | #ifdef CONFIG_64BIT |
69 | int vmbits; /* Virtual memory size in bits */ | 82 | int vmbits; /* Virtual memory size in bits */ |
70 | #endif | 83 | #endif |
71 | #ifdef CONFIG_MIPS_MT_SMP | 84 | #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) |
72 | /* | 85 | /* |
73 | * There is not necessarily a 1:1 mapping of VPE num to CPU number | 86 | * There is not necessarily a 1:1 mapping of VPE num to CPU number |
74 | * in particular on multi-core systems. | 87 | * in particular on multi-core systems. |
@@ -91,6 +104,11 @@ struct cpuinfo_mips { | |||
91 | * htw_start/htw_stop calls | 104 | * htw_start/htw_stop calls |
92 | */ | 105 | */ |
93 | unsigned int htw_seq; | 106 | unsigned int htw_seq; |
107 | |||
108 | /* VZ & Guest features */ | ||
109 | struct guest_info guest; | ||
110 | unsigned int gtoffset_mask; | ||
111 | unsigned int guestid_mask; | ||
94 | } __attribute__((aligned(SMP_CACHE_BYTES))); | 112 | } __attribute__((aligned(SMP_CACHE_BYTES))); |
95 | 113 | ||
96 | extern struct cpuinfo_mips cpu_data[]; | 114 | extern struct cpuinfo_mips cpu_data[]; |
@@ -125,10 +143,31 @@ struct proc_cpuinfo_notifier_args { | |||
125 | unsigned long n; | 143 | unsigned long n; |
126 | }; | 144 | }; |
127 | 145 | ||
128 | #ifdef CONFIG_MIPS_MT_SMP | 146 | #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) |
129 | # define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) | 147 | # define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) |
130 | #else | 148 | #else |
131 | # define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; }) | 149 | # define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; }) |
132 | #endif | 150 | #endif |
133 | 151 | ||
152 | static inline unsigned long cpu_asid_inc(void) | ||
153 | { | ||
154 | return 1 << CONFIG_MIPS_ASID_SHIFT; | ||
155 | } | ||
156 | |||
157 | static inline unsigned long cpu_asid_mask(struct cpuinfo_mips *cpuinfo) | ||
158 | { | ||
159 | #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE | ||
160 | return cpuinfo->asid_mask; | ||
161 | #endif | ||
162 | return ((1 << CONFIG_MIPS_ASID_BITS) - 1) << CONFIG_MIPS_ASID_SHIFT; | ||
163 | } | ||
164 | |||
165 | static inline void set_cpu_asid_mask(struct cpuinfo_mips *cpuinfo, | ||
166 | unsigned long asid_mask) | ||
167 | { | ||
168 | #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE | ||
169 | cpuinfo->asid_mask = asid_mask; | ||
170 | #endif | ||
171 | } | ||
172 | |||
134 | #endif /* __ASM_CPU_INFO_H */ | 173 | #endif /* __ASM_CPU_INFO_H */ |
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index abee2bfd10dc..fbe1881f28fc 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h | |||
@@ -77,8 +77,13 @@ static inline int __pure __get_cpu_type(const int cpu_type) | |||
77 | */ | 77 | */ |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | #ifdef CONFIG_SYS_HAS_CPU_MIPS32_R6 | ||
81 | case CPU_M6250: | ||
82 | #endif | ||
83 | |||
80 | #ifdef CONFIG_SYS_HAS_CPU_MIPS64_R6 | 84 | #ifdef CONFIG_SYS_HAS_CPU_MIPS64_R6 |
81 | case CPU_I6400: | 85 | case CPU_I6400: |
86 | case CPU_P6600: | ||
82 | #endif | 87 | #endif |
83 | 88 | ||
84 | #ifdef CONFIG_SYS_HAS_CPU_R3000 | 89 | #ifdef CONFIG_SYS_HAS_CPU_R3000 |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index a97ca97285ec..f672df8b26d0 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #define PRID_COMP_LEXRA 0x0b0000 | 42 | #define PRID_COMP_LEXRA 0x0b0000 |
43 | #define PRID_COMP_NETLOGIC 0x0c0000 | 43 | #define PRID_COMP_NETLOGIC 0x0c0000 |
44 | #define PRID_COMP_CAVIUM 0x0d0000 | 44 | #define PRID_COMP_CAVIUM 0x0d0000 |
45 | #define PRID_COMP_LOONGSON 0x140000 | ||
45 | #define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */ | 46 | #define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */ |
46 | #define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */ | 47 | #define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */ |
47 | #define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */ | 48 | #define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */ |
@@ -118,9 +119,11 @@ | |||
118 | #define PRID_IMP_INTERAPTIV_MP 0xa100 | 119 | #define PRID_IMP_INTERAPTIV_MP 0xa100 |
119 | #define PRID_IMP_PROAPTIV_UP 0xa200 | 120 | #define PRID_IMP_PROAPTIV_UP 0xa200 |
120 | #define PRID_IMP_PROAPTIV_MP 0xa300 | 121 | #define PRID_IMP_PROAPTIV_MP 0xa300 |
122 | #define PRID_IMP_P6600 0xa400 | ||
121 | #define PRID_IMP_M5150 0xa700 | 123 | #define PRID_IMP_M5150 0xa700 |
122 | #define PRID_IMP_P5600 0xa800 | 124 | #define PRID_IMP_P5600 0xa800 |
123 | #define PRID_IMP_I6400 0xa900 | 125 | #define PRID_IMP_I6400 0xa900 |
126 | #define PRID_IMP_M6250 0xab00 | ||
124 | 127 | ||
125 | /* | 128 | /* |
126 | * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE | 129 | * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE |
@@ -169,6 +172,8 @@ | |||
169 | #define PRID_IMP_CAVIUM_CNF71XX 0x9400 | 172 | #define PRID_IMP_CAVIUM_CNF71XX 0x9400 |
170 | #define PRID_IMP_CAVIUM_CN78XX 0x9500 | 173 | #define PRID_IMP_CAVIUM_CN78XX 0x9500 |
171 | #define PRID_IMP_CAVIUM_CN70XX 0x9600 | 174 | #define PRID_IMP_CAVIUM_CN70XX 0x9600 |
175 | #define PRID_IMP_CAVIUM_CN73XX 0x9700 | ||
176 | #define PRID_IMP_CAVIUM_CNF75XX 0x9800 | ||
172 | 177 | ||
173 | /* | 178 | /* |
174 | * These are the PRID's for when 23:16 == PRID_COMP_INGENIC_* | 179 | * These are the PRID's for when 23:16 == PRID_COMP_INGENIC_* |
@@ -237,9 +242,10 @@ | |||
237 | #define PRID_REV_LOONGSON1B 0x0020 | 242 | #define PRID_REV_LOONGSON1B 0x0020 |
238 | #define PRID_REV_LOONGSON2E 0x0002 | 243 | #define PRID_REV_LOONGSON2E 0x0002 |
239 | #define PRID_REV_LOONGSON2F 0x0003 | 244 | #define PRID_REV_LOONGSON2F 0x0003 |
240 | #define PRID_REV_LOONGSON3A 0x0005 | 245 | #define PRID_REV_LOONGSON3A_R1 0x0005 |
241 | #define PRID_REV_LOONGSON3B_R1 0x0006 | 246 | #define PRID_REV_LOONGSON3B_R1 0x0006 |
242 | #define PRID_REV_LOONGSON3B_R2 0x0007 | 247 | #define PRID_REV_LOONGSON3B_R2 0x0007 |
248 | #define PRID_REV_LOONGSON3A_R2 0x0008 | ||
243 | 249 | ||
244 | /* | 250 | /* |
245 | * Older processors used to encode processor version and revision in two | 251 | * Older processors used to encode processor version and revision in two |
@@ -307,8 +313,8 @@ enum cpu_type_enum { | |||
307 | CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, | 313 | CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, |
308 | CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, | 314 | CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, |
309 | CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC, | 315 | CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC, |
310 | CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K, CPU_M5150, | 316 | CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K, |
311 | CPU_I6400, | 317 | CPU_M5150, CPU_I6400, CPU_P6600, CPU_M6250, |
312 | 318 | ||
313 | /* | 319 | /* |
314 | * MIPS64 class processors | 320 | * MIPS64 class processors |
@@ -346,48 +352,68 @@ enum cpu_type_enum { | |||
346 | MIPS_CPU_ISA_M64R6) | 352 | MIPS_CPU_ISA_M64R6) |
347 | 353 | ||
348 | /* | 354 | /* |
355 | * Private version of BIT_ULL() to escape include file recursion hell. | ||
356 | * We soon will have to switch to another mechanism that will work with | ||
357 | * more than 64 bits anyway. | ||
358 | */ | ||
359 | #define MBIT_ULL(bit) (1ULL << (bit)) | ||
360 | |||
361 | /* | ||
349 | * CPU Option encodings | 362 | * CPU Option encodings |
350 | */ | 363 | */ |
351 | #define MIPS_CPU_TLB 0x00000001ull /* CPU has TLB */ | 364 | #define MIPS_CPU_TLB MBIT_ULL( 0) /* CPU has TLB */ |
352 | #define MIPS_CPU_4KEX 0x00000002ull /* "R4K" exception model */ | 365 | #define MIPS_CPU_4KEX MBIT_ULL( 1) /* "R4K" exception model */ |
353 | #define MIPS_CPU_3K_CACHE 0x00000004ull /* R3000-style caches */ | 366 | #define MIPS_CPU_3K_CACHE MBIT_ULL( 2) /* R3000-style caches */ |
354 | #define MIPS_CPU_4K_CACHE 0x00000008ull /* R4000-style caches */ | 367 | #define MIPS_CPU_4K_CACHE MBIT_ULL( 3) /* R4000-style caches */ |
355 | #define MIPS_CPU_TX39_CACHE 0x00000010ull /* TX3900-style caches */ | 368 | #define MIPS_CPU_TX39_CACHE MBIT_ULL( 4) /* TX3900-style caches */ |
356 | #define MIPS_CPU_FPU 0x00000020ull /* CPU has FPU */ | 369 | #define MIPS_CPU_FPU MBIT_ULL( 5) /* CPU has FPU */ |
357 | #define MIPS_CPU_32FPR 0x00000040ull /* 32 dbl. prec. FP registers */ | 370 | #define MIPS_CPU_32FPR MBIT_ULL( 6) /* 32 dbl. prec. FP registers */ |
358 | #define MIPS_CPU_COUNTER 0x00000080ull /* Cycle count/compare */ | 371 | #define MIPS_CPU_COUNTER MBIT_ULL( 7) /* Cycle count/compare */ |
359 | #define MIPS_CPU_WATCH 0x00000100ull /* watchpoint registers */ | 372 | #define MIPS_CPU_WATCH MBIT_ULL( 8) /* watchpoint registers */ |
360 | #define MIPS_CPU_DIVEC 0x00000200ull /* dedicated interrupt vector */ | 373 | #define MIPS_CPU_DIVEC MBIT_ULL( 9) /* dedicated interrupt vector */ |
361 | #define MIPS_CPU_VCE 0x00000400ull /* virt. coherence conflict possible */ | 374 | #define MIPS_CPU_VCE MBIT_ULL(10) /* virt. coherence conflict possible */ |
362 | #define MIPS_CPU_CACHE_CDEX_P 0x00000800ull /* Create_Dirty_Exclusive CACHE op */ | 375 | #define MIPS_CPU_CACHE_CDEX_P MBIT_ULL(11) /* Create_Dirty_Exclusive CACHE op */ |
363 | #define MIPS_CPU_CACHE_CDEX_S 0x00001000ull /* ... same for seconary cache ... */ | 376 | #define MIPS_CPU_CACHE_CDEX_S MBIT_ULL(12) /* ... same for seconary cache ... */ |
364 | #define MIPS_CPU_MCHECK 0x00002000ull /* Machine check exception */ | 377 | #define MIPS_CPU_MCHECK MBIT_ULL(13) /* Machine check exception */ |
365 | #define MIPS_CPU_EJTAG 0x00004000ull /* EJTAG exception */ | 378 | #define MIPS_CPU_EJTAG MBIT_ULL(14) /* EJTAG exception */ |
366 | #define MIPS_CPU_NOFPUEX 0x00008000ull /* no FPU exception */ | 379 | #define MIPS_CPU_NOFPUEX MBIT_ULL(15) /* no FPU exception */ |
367 | #define MIPS_CPU_LLSC 0x00010000ull /* CPU has ll/sc instructions */ | 380 | #define MIPS_CPU_LLSC MBIT_ULL(16) /* CPU has ll/sc instructions */ |
368 | #define MIPS_CPU_INCLUSIVE_CACHES 0x00020000ull /* P-cache subset enforced */ | 381 | #define MIPS_CPU_INCLUSIVE_CACHES MBIT_ULL(17) /* P-cache subset enforced */ |
369 | #define MIPS_CPU_PREFETCH 0x00040000ull /* CPU has usable prefetch */ | 382 | #define MIPS_CPU_PREFETCH MBIT_ULL(18) /* CPU has usable prefetch */ |
370 | #define MIPS_CPU_VINT 0x00080000ull /* CPU supports MIPSR2 vectored interrupts */ | 383 | #define MIPS_CPU_VINT MBIT_ULL(19) /* CPU supports MIPSR2 vectored interrupts */ |
371 | #define MIPS_CPU_VEIC 0x00100000ull /* CPU supports MIPSR2 external interrupt controller mode */ | 384 | #define MIPS_CPU_VEIC MBIT_ULL(20) /* CPU supports MIPSR2 external interrupt controller mode */ |
372 | #define MIPS_CPU_ULRI 0x00200000ull /* CPU has ULRI feature */ | 385 | #define MIPS_CPU_ULRI MBIT_ULL(21) /* CPU has ULRI feature */ |
373 | #define MIPS_CPU_PCI 0x00400000ull /* CPU has Perf Ctr Int indicator */ | 386 | #define MIPS_CPU_PCI MBIT_ULL(22) /* CPU has Perf Ctr Int indicator */ |
374 | #define MIPS_CPU_RIXI 0x00800000ull /* CPU has TLB Read/eXec Inhibit */ | 387 | #define MIPS_CPU_RIXI MBIT_ULL(23) /* CPU has TLB Read/eXec Inhibit */ |
375 | #define MIPS_CPU_MICROMIPS 0x01000000ull /* CPU has microMIPS capability */ | 388 | #define MIPS_CPU_MICROMIPS MBIT_ULL(24) /* CPU has microMIPS capability */ |
376 | #define MIPS_CPU_TLBINV 0x02000000ull /* CPU supports TLBINV/F */ | 389 | #define MIPS_CPU_TLBINV MBIT_ULL(25) /* CPU supports TLBINV/F */ |
377 | #define MIPS_CPU_SEGMENTS 0x04000000ull /* CPU supports Segmentation Control registers */ | 390 | #define MIPS_CPU_SEGMENTS MBIT_ULL(26) /* CPU supports Segmentation Control registers */ |
378 | #define MIPS_CPU_EVA 0x80000000ull /* CPU supports Enhanced Virtual Addressing */ | 391 | #define MIPS_CPU_EVA MBIT_ULL(27) /* CPU supports Enhanced Virtual Addressing */ |
379 | #define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ | 392 | #define MIPS_CPU_HTW MBIT_ULL(28) /* CPU support Hardware Page Table Walker */ |
380 | #define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ | 393 | #define MIPS_CPU_RIXIEX MBIT_ULL(29) /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ |
381 | #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ | 394 | #define MIPS_CPU_MAAR MBIT_ULL(30) /* MAAR(I) registers are present */ |
382 | #define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */ | 395 | #define MIPS_CPU_FRE MBIT_ULL(31) /* FRE & UFE bits implemented */ |
383 | #define MIPS_CPU_RW_LLB 0x1000000000ull /* LLADDR/LLB writes are allowed */ | 396 | #define MIPS_CPU_RW_LLB MBIT_ULL(32) /* LLADDR/LLB writes are allowed */ |
384 | #define MIPS_CPU_XPA 0x2000000000ull /* CPU supports Extended Physical Addressing */ | 397 | #define MIPS_CPU_LPA MBIT_ULL(33) /* CPU supports Large Physical Addressing */ |
385 | #define MIPS_CPU_CDMM 0x4000000000ull /* CPU has Common Device Memory Map */ | 398 | #define MIPS_CPU_CDMM MBIT_ULL(34) /* CPU has Common Device Memory Map */ |
386 | #define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */ | 399 | #define MIPS_CPU_BP_GHIST MBIT_ULL(35) /* R12K+ Branch Prediction Global History */ |
387 | #define MIPS_CPU_SP 0x10000000000ull /* Small (1KB) page support */ | 400 | #define MIPS_CPU_SP MBIT_ULL(36) /* Small (1KB) page support */ |
388 | #define MIPS_CPU_FTLB 0x20000000000ull /* CPU has Fixed-page-size TLB */ | 401 | #define MIPS_CPU_FTLB MBIT_ULL(37) /* CPU has Fixed-page-size TLB */ |
389 | #define MIPS_CPU_NAN_LEGACY 0x40000000000ull /* Legacy NaN implemented */ | 402 | #define MIPS_CPU_NAN_LEGACY MBIT_ULL(38) /* Legacy NaN implemented */ |
390 | #define MIPS_CPU_NAN_2008 0x80000000000ull /* 2008 NaN implemented */ | 403 | #define MIPS_CPU_NAN_2008 MBIT_ULL(39) /* 2008 NaN implemented */ |
404 | #define MIPS_CPU_VP MBIT_ULL(40) /* MIPSr6 Virtual Processors (multi-threading) */ | ||
405 | #define MIPS_CPU_LDPTE MBIT_ULL(41) /* CPU has ldpte/lddir instructions */ | ||
406 | #define MIPS_CPU_MVH MBIT_ULL(42) /* CPU supports MFHC0/MTHC0 */ | ||
407 | #define MIPS_CPU_EBASE_WG MBIT_ULL(43) /* CPU has EBase.WG */ | ||
408 | #define MIPS_CPU_BADINSTR MBIT_ULL(44) /* CPU has BadInstr register */ | ||
409 | #define MIPS_CPU_BADINSTRP MBIT_ULL(45) /* CPU has BadInstrP register */ | ||
410 | #define MIPS_CPU_CTXTC MBIT_ULL(46) /* CPU has [X]ConfigContext registers */ | ||
411 | #define MIPS_CPU_PERF MBIT_ULL(47) /* CPU has MIPS performance counters */ | ||
412 | #define MIPS_CPU_GUESTCTL0EXT MBIT_ULL(48) /* CPU has VZ GuestCtl0Ext register */ | ||
413 | #define MIPS_CPU_GUESTCTL1 MBIT_ULL(49) /* CPU has VZ GuestCtl1 register */ | ||
414 | #define MIPS_CPU_GUESTCTL2 MBIT_ULL(50) /* CPU has VZ GuestCtl2 register */ | ||
415 | #define MIPS_CPU_GUESTID MBIT_ULL(51) /* CPU uses VZ ASE GuestID feature */ | ||
416 | #define MIPS_CPU_DRG MBIT_ULL(52) /* CPU has VZ Direct Root to Guest (DRG) */ | ||
391 | 417 | ||
392 | /* | 418 | /* |
393 | * CPU ASE encodings | 419 | * CPU ASE encodings |
@@ -401,5 +427,6 @@ enum cpu_type_enum { | |||
401 | #define MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */ | 427 | #define MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */ |
402 | #define MIPS_ASE_VZ 0x00000080 /* Virtualization ASE */ | 428 | #define MIPS_ASE_VZ 0x00000080 /* Virtualization ASE */ |
403 | #define MIPS_ASE_MSA 0x00000100 /* MIPS SIMD Architecture */ | 429 | #define MIPS_ASE_MSA 0x00000100 /* MIPS SIMD Architecture */ |
430 | #define MIPS_ASE_DSP3 0x00000200 /* Signal Processing ASE Rev 3*/ | ||
404 | 431 | ||
405 | #endif /* _ASM_CPU_H */ | 432 | #endif /* _ASM_CPU_H */ |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index e090fc388e02..f5f45717968e 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -111,6 +111,11 @@ | |||
111 | #define R_MIPS_CALLHI16 30 | 111 | #define R_MIPS_CALLHI16 30 |
112 | #define R_MIPS_CALLLO16 31 | 112 | #define R_MIPS_CALLLO16 31 |
113 | /* | 113 | /* |
114 | * Introduced for MIPSr6. | ||
115 | */ | ||
116 | #define R_MIPS_PC21_S2 60 | ||
117 | #define R_MIPS_PC26_S2 61 | ||
118 | /* | ||
114 | * This range is reserved for vendor specific relocations. | 119 | * This range is reserved for vendor specific relocations. |
115 | */ | 120 | */ |
116 | #define R_MIPS_LOVENDOR 100 | 121 | #define R_MIPS_LOVENDOR 100 |
@@ -170,16 +175,14 @@ | |||
170 | #define SHF_MIPS_NAMES 0x02000000 | 175 | #define SHF_MIPS_NAMES 0x02000000 |
171 | #define SHF_MIPS_NODUPES 0x01000000 | 176 | #define SHF_MIPS_NODUPES 0x01000000 |
172 | 177 | ||
173 | #ifndef ELF_ARCH | 178 | #define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */ |
174 | /* ELF register definitions */ | 179 | #define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */ |
175 | #define ELF_NGREG 45 | 180 | #define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */ |
176 | #define ELF_NFPREG 33 | 181 | #define MIPS_ABI_FP_SOFT 3 /* -msoft-float */ |
177 | 182 | #define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */ | |
178 | typedef unsigned long elf_greg_t; | 183 | #define MIPS_ABI_FP_XX 5 /* -mfpxx */ |
179 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | 184 | #define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */ |
180 | 185 | #define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */ | |
181 | typedef double elf_fpreg_t; | ||
182 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | ||
183 | 186 | ||
184 | struct mips_elf_abiflags_v0 { | 187 | struct mips_elf_abiflags_v0 { |
185 | uint16_t version; /* Version of flags structure */ | 188 | uint16_t version; /* Version of flags structure */ |
@@ -196,16 +199,54 @@ struct mips_elf_abiflags_v0 { | |||
196 | uint32_t flags2; | 199 | uint32_t flags2; |
197 | }; | 200 | }; |
198 | 201 | ||
199 | #define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */ | 202 | #ifndef ELF_ARCH |
200 | #define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */ | 203 | /* ELF register definitions */ |
201 | #define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */ | 204 | #define ELF_NGREG 45 |
202 | #define MIPS_ABI_FP_SOFT 3 /* -msoft-float */ | 205 | #define ELF_NFPREG 33 |
203 | #define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */ | 206 | |
204 | #define MIPS_ABI_FP_XX 5 /* -mfpxx */ | 207 | typedef unsigned long elf_greg_t; |
205 | #define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */ | 208 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
206 | #define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */ | 209 | |
210 | typedef double elf_fpreg_t; | ||
211 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | ||
207 | 212 | ||
208 | #ifdef CONFIG_32BIT | 213 | #ifdef CONFIG_32BIT |
214 | /* | ||
215 | * This is used to ensure we don't load something for the wrong architecture. | ||
216 | */ | ||
217 | #define elf_check_arch elfo32_check_arch | ||
218 | |||
219 | /* | ||
220 | * These are used to set parameters in the core dumps. | ||
221 | */ | ||
222 | #define ELF_CLASS ELFCLASS32 | ||
223 | |||
224 | #endif /* CONFIG_32BIT */ | ||
225 | |||
226 | #ifdef CONFIG_64BIT | ||
227 | /* | ||
228 | * This is used to ensure we don't load something for the wrong architecture. | ||
229 | */ | ||
230 | #define elf_check_arch elfn64_check_arch | ||
231 | |||
232 | /* | ||
233 | * These are used to set parameters in the core dumps. | ||
234 | */ | ||
235 | #define ELF_CLASS ELFCLASS64 | ||
236 | |||
237 | #endif /* CONFIG_64BIT */ | ||
238 | |||
239 | /* | ||
240 | * These are used to set parameters in the core dumps. | ||
241 | */ | ||
242 | #ifdef __MIPSEB__ | ||
243 | #define ELF_DATA ELFDATA2MSB | ||
244 | #elif defined(__MIPSEL__) | ||
245 | #define ELF_DATA ELFDATA2LSB | ||
246 | #endif | ||
247 | #define ELF_ARCH EM_MIPS | ||
248 | |||
249 | #endif /* !defined(ELF_ARCH) */ | ||
209 | 250 | ||
210 | /* | 251 | /* |
211 | * In order to be sure that we don't attempt to execute an O32 binary which | 252 | * In order to be sure that we don't attempt to execute an O32 binary which |
@@ -219,10 +260,15 @@ struct mips_elf_abiflags_v0 { | |||
219 | # define __MIPS_O32_FP64_MUST_BE_ZERO EF_MIPS_FP64 | 260 | # define __MIPS_O32_FP64_MUST_BE_ZERO EF_MIPS_FP64 |
220 | #endif | 261 | #endif |
221 | 262 | ||
263 | #define mips_elf_check_machine(x) ((x)->e_machine == EM_MIPS) | ||
264 | |||
265 | #define vmcore_elf32_check_arch mips_elf_check_machine | ||
266 | #define vmcore_elf64_check_arch mips_elf_check_machine | ||
267 | |||
222 | /* | 268 | /* |
223 | * This is used to ensure we don't load something for the wrong architecture. | 269 | * Return non-zero if HDR identifies an o32 ELF binary. |
224 | */ | 270 | */ |
225 | #define elf_check_arch(hdr) \ | 271 | #define elfo32_check_arch(hdr) \ |
226 | ({ \ | 272 | ({ \ |
227 | int __res = 1; \ | 273 | int __res = 1; \ |
228 | struct elfhdr *__h = (hdr); \ | 274 | struct elfhdr *__h = (hdr); \ |
@@ -243,17 +289,9 @@ struct mips_elf_abiflags_v0 { | |||
243 | }) | 289 | }) |
244 | 290 | ||
245 | /* | 291 | /* |
246 | * These are used to set parameters in the core dumps. | 292 | * Return non-zero if HDR identifies an n64 ELF binary. |
247 | */ | ||
248 | #define ELF_CLASS ELFCLASS32 | ||
249 | |||
250 | #endif /* CONFIG_32BIT */ | ||
251 | |||
252 | #ifdef CONFIG_64BIT | ||
253 | /* | ||
254 | * This is used to ensure we don't load something for the wrong architecture. | ||
255 | */ | 293 | */ |
256 | #define elf_check_arch(hdr) \ | 294 | #define elfn64_check_arch(hdr) \ |
257 | ({ \ | 295 | ({ \ |
258 | int __res = 1; \ | 296 | int __res = 1; \ |
259 | struct elfhdr *__h = (hdr); \ | 297 | struct elfhdr *__h = (hdr); \ |
@@ -267,28 +305,23 @@ struct mips_elf_abiflags_v0 { | |||
267 | }) | 305 | }) |
268 | 306 | ||
269 | /* | 307 | /* |
270 | * These are used to set parameters in the core dumps. | 308 | * Return non-zero if HDR identifies an n32 ELF binary. |
271 | */ | 309 | */ |
272 | #define ELF_CLASS ELFCLASS64 | 310 | #define elfn32_check_arch(hdr) \ |
273 | 311 | ({ \ | |
274 | #endif /* CONFIG_64BIT */ | 312 | int __res = 1; \ |
275 | 313 | struct elfhdr *__h = (hdr); \ | |
276 | /* | 314 | \ |
277 | * These are used to set parameters in the core dumps. | 315 | if (!mips_elf_check_machine(__h)) \ |
278 | */ | 316 | __res = 0; \ |
279 | #ifdef __MIPSEB__ | 317 | if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ |
280 | #define ELF_DATA ELFDATA2MSB | 318 | __res = 0; \ |
281 | #elif defined(__MIPSEL__) | 319 | if (((__h->e_flags & EF_MIPS_ABI2) == 0) || \ |
282 | #define ELF_DATA ELFDATA2LSB | 320 | ((__h->e_flags & EF_MIPS_ABI) != 0)) \ |
283 | #endif | 321 | __res = 0; \ |
284 | #define ELF_ARCH EM_MIPS | 322 | \ |
285 | 323 | __res; \ | |
286 | #endif /* !defined(ELF_ARCH) */ | 324 | }) |
287 | |||
288 | #define mips_elf_check_machine(x) ((x)->e_machine == EM_MIPS) | ||
289 | |||
290 | #define vmcore_elf32_check_arch mips_elf_check_machine | ||
291 | #define vmcore_elf64_check_arch mips_elf_check_machine | ||
292 | 325 | ||
293 | struct mips_abi; | 326 | struct mips_abi; |
294 | 327 | ||
@@ -300,17 +333,16 @@ extern struct mips_abi mips_abi_n32; | |||
300 | 333 | ||
301 | #define SET_PERSONALITY2(ex, state) \ | 334 | #define SET_PERSONALITY2(ex, state) \ |
302 | do { \ | 335 | do { \ |
303 | if (personality(current->personality) != PER_LINUX) \ | ||
304 | set_personality(PER_LINUX); \ | ||
305 | \ | ||
306 | clear_thread_flag(TIF_HYBRID_FPREGS); \ | 336 | clear_thread_flag(TIF_HYBRID_FPREGS); \ |
307 | set_thread_flag(TIF_32BIT_FPREGS); \ | 337 | set_thread_flag(TIF_32BIT_FPREGS); \ |
308 | \ | 338 | \ |
309 | mips_set_personality_fp(state); \ | ||
310 | \ | ||
311 | current->thread.abi = &mips_abi; \ | 339 | current->thread.abi = &mips_abi; \ |
312 | \ | 340 | \ |
341 | mips_set_personality_fp(state); \ | ||
313 | mips_set_personality_nan(state); \ | 342 | mips_set_personality_nan(state); \ |
343 | \ | ||
344 | if (personality(current->personality) != PER_LINUX) \ | ||
345 | set_personality(PER_LINUX); \ | ||
314 | } while (0) | 346 | } while (0) |
315 | 347 | ||
316 | #endif /* CONFIG_32BIT */ | 348 | #endif /* CONFIG_32BIT */ |
@@ -321,6 +353,7 @@ do { \ | |||
321 | #define __SET_PERSONALITY32_N32() \ | 353 | #define __SET_PERSONALITY32_N32() \ |
322 | do { \ | 354 | do { \ |
323 | set_thread_flag(TIF_32BIT_ADDR); \ | 355 | set_thread_flag(TIF_32BIT_ADDR); \ |
356 | \ | ||
324 | current->thread.abi = &mips_abi_n32; \ | 357 | current->thread.abi = &mips_abi_n32; \ |
325 | } while (0) | 358 | } while (0) |
326 | #else | 359 | #else |
@@ -336,9 +369,9 @@ do { \ | |||
336 | clear_thread_flag(TIF_HYBRID_FPREGS); \ | 369 | clear_thread_flag(TIF_HYBRID_FPREGS); \ |
337 | set_thread_flag(TIF_32BIT_FPREGS); \ | 370 | set_thread_flag(TIF_32BIT_FPREGS); \ |
338 | \ | 371 | \ |
339 | mips_set_personality_fp(state); \ | ||
340 | \ | ||
341 | current->thread.abi = &mips_abi_32; \ | 372 | current->thread.abi = &mips_abi_32; \ |
373 | \ | ||
374 | mips_set_personality_fp(state); \ | ||
342 | } while (0) | 375 | } while (0) |
343 | #else | 376 | #else |
344 | #define __SET_PERSONALITY32_O32(ex, state) \ | 377 | #define __SET_PERSONALITY32_O32(ex, state) \ |
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h index 7b99efd31074..dbb1eb6e284f 100644 --- a/arch/mips/include/asm/hazards.h +++ b/arch/mips/include/asm/hazards.h | |||
@@ -22,7 +22,8 @@ | |||
22 | /* | 22 | /* |
23 | * TLB hazards | 23 | * TLB hazards |
24 | */ | 24 | */ |
25 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) && !defined(CONFIG_CPU_CAVIUM_OCTEON) | 25 | #if (defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)) && \ |
26 | !defined(CONFIG_CPU_CAVIUM_OCTEON) && !defined(CONFIG_LOONGSON3_ENHANCEMENT) | ||
26 | 27 | ||
27 | /* | 28 | /* |
28 | * MIPSR2 defines ehb for hazard avoidance | 29 | * MIPSR2 defines ehb for hazard avoidance |
@@ -155,8 +156,8 @@ do { \ | |||
155 | } while (0) | 156 | } while (0) |
156 | 157 | ||
157 | #elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \ | 158 | #elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \ |
158 | defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \ | 159 | defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_LOONGSON3_ENHANCEMENT) || \ |
159 | defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR) | 160 | defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR) |
160 | 161 | ||
161 | /* | 162 | /* |
162 | * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. | 163 | * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. |
diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 01880b34a209..64f2500d891b 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h | |||
@@ -19,8 +19,10 @@ | |||
19 | 19 | ||
20 | #ifdef __KERNEL__ | 20 | #ifdef __KERNEL__ |
21 | 21 | ||
22 | #include <linux/bug.h> | ||
22 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
23 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
25 | #include <asm/cpu-features.h> | ||
24 | #include <asm/kmap_types.h> | 26 | #include <asm/kmap_types.h> |
25 | 27 | ||
26 | /* undef for production */ | 28 | /* undef for production */ |
@@ -50,7 +52,7 @@ extern void *kmap_atomic(struct page *page); | |||
50 | extern void __kunmap_atomic(void *kvaddr); | 52 | extern void __kunmap_atomic(void *kvaddr); |
51 | extern void *kmap_atomic_pfn(unsigned long pfn); | 53 | extern void *kmap_atomic_pfn(unsigned long pfn); |
52 | 54 | ||
53 | #define flush_cache_kmaps() flush_cache_all() | 55 | #define flush_cache_kmaps() BUG_ON(cpu_has_dc_aliases) |
54 | 56 | ||
55 | extern void kmap_init(void); | 57 | extern void kmap_init(void); |
56 | 58 | ||
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 2b4dc7ad53b8..ecabc00c1e66 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
@@ -304,10 +304,10 @@ static inline void iounmap(const volatile void __iomem *addr) | |||
304 | #undef __IS_KSEG1 | 304 | #undef __IS_KSEG1 |
305 | } | 305 | } |
306 | 306 | ||
307 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | 307 | #if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_LOONGSON3_ENHANCEMENT) |
308 | #define war_octeon_io_reorder_wmb() wmb() | 308 | #define war_io_reorder_wmb() wmb() |
309 | #else | 309 | #else |
310 | #define war_octeon_io_reorder_wmb() do { } while (0) | 310 | #define war_io_reorder_wmb() do { } while (0) |
311 | #endif | 311 | #endif |
312 | 312 | ||
313 | #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ | 313 | #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ |
@@ -318,7 +318,7 @@ static inline void pfx##write##bwlq(type val, \ | |||
318 | volatile type *__mem; \ | 318 | volatile type *__mem; \ |
319 | type __val; \ | 319 | type __val; \ |
320 | \ | 320 | \ |
321 | war_octeon_io_reorder_wmb(); \ | 321 | war_io_reorder_wmb(); \ |
322 | \ | 322 | \ |
323 | __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \ | 323 | __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \ |
324 | \ | 324 | \ |
@@ -387,7 +387,7 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \ | |||
387 | volatile type *__addr; \ | 387 | volatile type *__addr; \ |
388 | type __val; \ | 388 | type __val; \ |
389 | \ | 389 | \ |
390 | war_octeon_io_reorder_wmb(); \ | 390 | war_io_reorder_wmb(); \ |
391 | \ | 391 | \ |
392 | __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \ | 392 | __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \ |
393 | \ | 393 | \ |
diff --git a/arch/mips/include/asm/irq_regs.h b/arch/mips/include/asm/irq_regs.h index 33bd2a06de57..8c48d6dd1d78 100644 --- a/arch/mips/include/asm/irq_regs.h +++ b/arch/mips/include/asm/irq_regs.h | |||
@@ -18,4 +18,14 @@ static inline struct pt_regs *get_irq_regs(void) | |||
18 | return current_thread_info()->regs; | 18 | return current_thread_info()->regs; |
19 | } | 19 | } |
20 | 20 | ||
21 | static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) | ||
22 | { | ||
23 | struct pt_regs *old_regs; | ||
24 | |||
25 | old_regs = get_irq_regs(); | ||
26 | current_thread_info()->regs = new_regs; | ||
27 | |||
28 | return old_regs; | ||
29 | } | ||
30 | |||
21 | #endif /* __ASM_IRQ_REGS_H */ | 31 | #endif /* __ASM_IRQ_REGS_H */ |
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 65c351e328cc..9d3610be2323 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h | |||
@@ -41,7 +41,12 @@ static inline unsigned long arch_local_irq_save(void) | |||
41 | " .set push \n" | 41 | " .set push \n" |
42 | " .set reorder \n" | 42 | " .set reorder \n" |
43 | " .set noat \n" | 43 | " .set noat \n" |
44 | #if defined(CONFIG_CPU_LOONGSON3) | ||
45 | " mfc0 %[flags], $12 \n" | ||
46 | " di \n" | ||
47 | #else | ||
44 | " di %[flags] \n" | 48 | " di %[flags] \n" |
49 | #endif | ||
45 | " andi %[flags], 1 \n" | 50 | " andi %[flags], 1 \n" |
46 | " " __stringify(__irq_disable_hazard) " \n" | 51 | " " __stringify(__irq_disable_hazard) " \n" |
47 | " .set pop \n" | 52 | " .set pop \n" |
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index f6b12790716c..b76e132c87e4 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h | |||
@@ -311,17 +311,18 @@ enum emulation_result { | |||
311 | #define MIPS3_PG_FRAME 0x3fffffc0 | 311 | #define MIPS3_PG_FRAME 0x3fffffc0 |
312 | 312 | ||
313 | #define VPN2_MASK 0xffffe000 | 313 | #define VPN2_MASK 0xffffe000 |
314 | #define KVM_ENTRYHI_ASID MIPS_ENTRYHI_ASID | ||
314 | #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && \ | 315 | #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && \ |
315 | ((x).tlb_lo1 & MIPS3_PG_G)) | 316 | ((x).tlb_lo1 & MIPS3_PG_G)) |
316 | #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) | 317 | #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) |
317 | #define TLB_ASID(x) ((x).tlb_hi & ASID_MASK) | 318 | #define TLB_ASID(x) ((x).tlb_hi & KVM_ENTRYHI_ASID) |
318 | #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) \ | 319 | #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) \ |
319 | ? ((x).tlb_lo1 & MIPS3_PG_V) \ | 320 | ? ((x).tlb_lo1 & MIPS3_PG_V) \ |
320 | : ((x).tlb_lo0 & MIPS3_PG_V)) | 321 | : ((x).tlb_lo0 & MIPS3_PG_V)) |
321 | #define TLB_HI_VPN2_HIT(x, y) ((TLB_VPN2(x) & ~(x).tlb_mask) == \ | 322 | #define TLB_HI_VPN2_HIT(x, y) ((TLB_VPN2(x) & ~(x).tlb_mask) == \ |
322 | ((y) & VPN2_MASK & ~(x).tlb_mask)) | 323 | ((y) & VPN2_MASK & ~(x).tlb_mask)) |
323 | #define TLB_HI_ASID_HIT(x, y) (TLB_IS_GLOBAL(x) || \ | 324 | #define TLB_HI_ASID_HIT(x, y) (TLB_IS_GLOBAL(x) || \ |
324 | TLB_ASID(x) == ((y) & ASID_MASK)) | 325 | TLB_ASID(x) == ((y) & KVM_ENTRYHI_ASID)) |
325 | 326 | ||
326 | struct kvm_mips_tlb { | 327 | struct kvm_mips_tlb { |
327 | long tlb_mask; | 328 | long tlb_mask; |
diff --git a/arch/mips/include/asm/llsc.h b/arch/mips/include/asm/llsc.h new file mode 100644 index 000000000000..c6d17d171147 --- /dev/null +++ b/arch/mips/include/asm/llsc.h | |||
@@ -0,0 +1,28 @@ | |||
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 | * Macros for 32/64-bit neutral inline assembler | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_LLSC_H | ||
10 | #define __ASM_LLSC_H | ||
11 | |||
12 | #if _MIPS_SZLONG == 32 | ||
13 | #define SZLONG_LOG 5 | ||
14 | #define SZLONG_MASK 31UL | ||
15 | #define __LL "ll " | ||
16 | #define __SC "sc " | ||
17 | #define __INS "ins " | ||
18 | #define __EXT "ext " | ||
19 | #elif _MIPS_SZLONG == 64 | ||
20 | #define SZLONG_LOG 6 | ||
21 | #define SZLONG_MASK 63UL | ||
22 | #define __LL "lld " | ||
23 | #define __SC "scd " | ||
24 | #define __INS "dins " | ||
25 | #define __EXT "dext " | ||
26 | #endif | ||
27 | |||
28 | #endif /* __ASM_LLSC_H */ | ||
diff --git a/arch/mips/include/asm/mach-bmips/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bmips/cpu-feature-overrides.h new file mode 100644 index 000000000000..fa0583e1ce0d --- /dev/null +++ b/arch/mips/include/asm/mach-bmips/cpu-feature-overrides.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef __ASM_MACH_BMIPS_CPU_FEATURE_OVERRIDES_H | ||
2 | #define __ASM_MACH_BMIPS_CPU_FEATURE_OVERRIDES_H | ||
3 | |||
4 | /* Invariants across all BMIPS processors */ | ||
5 | #define cpu_has_vtag_icache 0 | ||
6 | #define cpu_icache_snoops_remote_store 1 | ||
7 | |||
8 | /* Processor ISA compatibility is MIPS32R1 */ | ||
9 | #define cpu_has_mips32r1 1 | ||
10 | #define cpu_has_mips32r2 0 | ||
11 | #define cpu_has_mips64r1 0 | ||
12 | #define cpu_has_mips64r2 0 | ||
13 | |||
14 | #endif /* __ASM_MACH_BMIPS_CPU_FEATURE_OVERRIDES_H */ | ||
diff --git a/arch/mips/include/asm/mach-bmips/ioremap.h b/arch/mips/include/asm/mach-bmips/ioremap.h new file mode 100644 index 000000000000..29c7a7bb7080 --- /dev/null +++ b/arch/mips/include/asm/mach-bmips/ioremap.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef __ASM_MACH_BMIPS_IOREMAP_H | ||
2 | #define __ASM_MACH_BMIPS_IOREMAP_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) | ||
7 | { | ||
8 | return phys_addr; | ||
9 | } | ||
10 | |||
11 | static inline int is_bmips_internal_registers(phys_addr_t offset) | ||
12 | { | ||
13 | if (offset >= 0xfff80000) | ||
14 | return 1; | ||
15 | |||
16 | return 0; | ||
17 | } | ||
18 | |||
19 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, | ||
20 | unsigned long flags) | ||
21 | { | ||
22 | if (is_bmips_internal_registers(offset)) | ||
23 | return (void __iomem *)offset; | ||
24 | |||
25 | return NULL; | ||
26 | } | ||
27 | |||
28 | static inline int plat_iounmap(const volatile void __iomem *addr) | ||
29 | { | ||
30 | return is_bmips_internal_registers((unsigned long)addr); | ||
31 | } | ||
32 | |||
33 | #endif /* __ASM_MACH_BMIPS_IOREMAP_H */ | ||
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h index 32cfbe6a191b..073b8bfbb3b3 100644 --- a/arch/mips/include/asm/mach-jz4740/platform.h +++ b/arch/mips/include/asm/mach-jz4740/platform.h | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | 21 | ||
22 | extern struct platform_device jz4740_usb_ohci_device; | ||
23 | extern struct platform_device jz4740_udc_device; | 22 | extern struct platform_device jz4740_udc_device; |
24 | extern struct platform_device jz4740_udc_xceiv_device; | 23 | extern struct platform_device jz4740_udc_xceiv_device; |
25 | extern struct platform_device jz4740_mmc_device; | 24 | extern struct platform_device jz4740_mmc_device; |
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h index 98d6a2f14aaf..7023883ca50f 100644 --- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h +++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _LTQ_FALCON_H__ | 9 | #ifndef _LTQ_FALCON_H__ |
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h index 4e5ae6523cb4..8064d7a4b33d 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | #ifndef _LANTIQ_H__ | 8 | #ifndef _LANTIQ_H__ |
9 | #define _LANTIQ_H__ | 9 | #define _LANTIQ_H__ |
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h index e23bf7c9a2d0..17d2fdcdaef4 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _LANTIQ_PLATFORM_H__ | 9 | #ifndef _LANTIQ_PLATFORM_H__ |
diff --git a/arch/mips/include/asm/mach-lantiq/xway/irq.h b/arch/mips/include/asm/mach-lantiq/xway/irq.h index a1471d2dd0d2..83e5f03cccb5 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/irq.h +++ b/arch/mips/include/asm/mach-lantiq/xway/irq.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef __LANTIQ_IRQ_H | 9 | #ifndef __LANTIQ_IRQ_H |
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h index 5eadfe582529..141076325307 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _LANTIQ_XWAY_IRQ_H__ | 9 | #ifndef _LANTIQ_XWAY_IRQ_H__ |
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h index dd6005b75e0c..f87310755319 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _LTQ_XWAY_H__ | 9 | #ifndef _LTQ_XWAY_H__ |
diff --git a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h index 5f8693d5ab12..4901833498f7 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h +++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h | |||
@@ -12,7 +12,7 @@ | |||
12 | * along with this program; if not, write to the Free Software | 12 | * along with this program; if not, write to the Free Software |
13 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 13 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
14 | * | 14 | * |
15 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | 15 | * Copyright (C) 2011 John Crispin <john@phrozen.org> |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #ifndef LTQ_DMA_H__ | 18 | #ifndef LTQ_DMA_H__ |
diff --git a/arch/mips/include/asm/mach-loongson32/cpufreq.h b/arch/mips/include/asm/mach-loongson32/cpufreq.h index 6843fa1a608d..2f1ecb081223 100644 --- a/arch/mips/include/asm/mach-loongson32/cpufreq.h +++ b/arch/mips/include/asm/mach-loongson32/cpufreq.h | |||
@@ -9,7 +9,6 @@ | |||
9 | * option) any later version. | 9 | * option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | |||
13 | #ifndef __ASM_MACH_LOONGSON32_CPUFREQ_H | 12 | #ifndef __ASM_MACH_LOONGSON32_CPUFREQ_H |
14 | #define __ASM_MACH_LOONGSON32_CPUFREQ_H | 13 | #define __ASM_MACH_LOONGSON32_CPUFREQ_H |
15 | 14 | ||
diff --git a/arch/mips/include/asm/mach-loongson32/dma.h b/arch/mips/include/asm/mach-loongson32/dma.h new file mode 100644 index 000000000000..ad1dec743ccc --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/dma.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Zhang, Keguang <keguang.zhang@gmail.com> | ||
3 | * | ||
4 | * Loongson 1 NAND platform support. | ||
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 | |||
12 | #ifndef __ASM_MACH_LOONGSON32_DMA_H | ||
13 | #define __ASM_MACH_LOONGSON32_DMA_H | ||
14 | |||
15 | #define LS1X_DMA_CHANNEL0 0 | ||
16 | #define LS1X_DMA_CHANNEL1 1 | ||
17 | #define LS1X_DMA_CHANNEL2 2 | ||
18 | |||
19 | struct plat_ls1x_dma { | ||
20 | int nr_channels; | ||
21 | }; | ||
22 | |||
23 | extern struct plat_ls1x_dma ls1b_dma_pdata; | ||
24 | |||
25 | #endif /* __ASM_MACH_LOONGSON32_DMA_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson32/irq.h b/arch/mips/include/asm/mach-loongson32/irq.h index 0d35b994e8d2..c1c744197de4 100644 --- a/arch/mips/include/asm/mach-loongson32/irq.h +++ b/arch/mips/include/asm/mach-loongson32/irq.h | |||
@@ -9,7 +9,6 @@ | |||
9 | * option) any later version. | 9 | * option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | |||
13 | #ifndef __ASM_MACH_LOONGSON32_IRQ_H | 12 | #ifndef __ASM_MACH_LOONGSON32_IRQ_H |
14 | #define __ASM_MACH_LOONGSON32_IRQ_H | 13 | #define __ASM_MACH_LOONGSON32_IRQ_H |
15 | 14 | ||
diff --git a/arch/mips/include/asm/mach-loongson32/loongson1.h b/arch/mips/include/asm/mach-loongson32/loongson1.h index 12aa129aad80..978f6df8970a 100644 --- a/arch/mips/include/asm/mach-loongson32/loongson1.h +++ b/arch/mips/include/asm/mach-loongson32/loongson1.h | |||
@@ -9,7 +9,6 @@ | |||
9 | * option) any later version. | 9 | * option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | |||
13 | #ifndef __ASM_MACH_LOONGSON32_LOONGSON1_H | 12 | #ifndef __ASM_MACH_LOONGSON32_LOONGSON1_H |
14 | #define __ASM_MACH_LOONGSON32_LOONGSON1_H | 13 | #define __ASM_MACH_LOONGSON32_LOONGSON1_H |
15 | 14 | ||
@@ -18,6 +17,9 @@ | |||
18 | /* Loongson 1 Register Bases */ | 17 | /* Loongson 1 Register Bases */ |
19 | #define LS1X_MUX_BASE 0x1fd00420 | 18 | #define LS1X_MUX_BASE 0x1fd00420 |
20 | #define LS1X_INTC_BASE 0x1fd01040 | 19 | #define LS1X_INTC_BASE 0x1fd01040 |
20 | #define LS1X_GPIO0_BASE 0x1fd010c0 | ||
21 | #define LS1X_GPIO1_BASE 0x1fd010c4 | ||
22 | #define LS1X_DMAC_BASE 0x1fd01160 | ||
21 | #define LS1X_EHCI_BASE 0x1fe00000 | 23 | #define LS1X_EHCI_BASE 0x1fe00000 |
22 | #define LS1X_OHCI_BASE 0x1fe08000 | 24 | #define LS1X_OHCI_BASE 0x1fe08000 |
23 | #define LS1X_GMAC0_BASE 0x1fe10000 | 25 | #define LS1X_GMAC0_BASE 0x1fe10000 |
diff --git a/arch/mips/include/asm/mach-loongson32/nand.h b/arch/mips/include/asm/mach-loongson32/nand.h new file mode 100644 index 000000000000..e274912e9de1 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/nand.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Zhang, Keguang <keguang.zhang@gmail.com> | ||
3 | * | ||
4 | * Loongson 1 NAND platform support. | ||
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 | |||
12 | #ifndef __ASM_MACH_LOONGSON32_NAND_H | ||
13 | #define __ASM_MACH_LOONGSON32_NAND_H | ||
14 | |||
15 | #include <linux/dmaengine.h> | ||
16 | #include <linux/mtd/partitions.h> | ||
17 | |||
18 | struct plat_ls1x_nand { | ||
19 | struct mtd_partition *parts; | ||
20 | unsigned int nr_parts; | ||
21 | |||
22 | int hold_cycle; | ||
23 | int wait_cycle; | ||
24 | }; | ||
25 | |||
26 | extern struct plat_ls1x_nand ls1b_nand_pdata; | ||
27 | |||
28 | bool ls1x_dma_filter_fn(struct dma_chan *chan, void *param); | ||
29 | |||
30 | #endif /* __ASM_MACH_LOONGSON32_NAND_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson32/platform.h b/arch/mips/include/asm/mach-loongson32/platform.h index c32f03f3f72c..672531aa9bef 100644 --- a/arch/mips/include/asm/mach-loongson32/platform.h +++ b/arch/mips/include/asm/mach-loongson32/platform.h | |||
@@ -7,20 +7,28 @@ | |||
7 | * option) any later version. | 7 | * option) any later version. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | |||
11 | #ifndef __ASM_MACH_LOONGSON32_PLATFORM_H | 10 | #ifndef __ASM_MACH_LOONGSON32_PLATFORM_H |
12 | #define __ASM_MACH_LOONGSON32_PLATFORM_H | 11 | #define __ASM_MACH_LOONGSON32_PLATFORM_H |
13 | 12 | ||
14 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
15 | 14 | ||
15 | #include <dma.h> | ||
16 | #include <nand.h> | ||
17 | |||
16 | extern struct platform_device ls1x_uart_pdev; | 18 | extern struct platform_device ls1x_uart_pdev; |
17 | extern struct platform_device ls1x_cpufreq_pdev; | 19 | extern struct platform_device ls1x_cpufreq_pdev; |
20 | extern struct platform_device ls1x_dma_pdev; | ||
18 | extern struct platform_device ls1x_eth0_pdev; | 21 | extern struct platform_device ls1x_eth0_pdev; |
19 | extern struct platform_device ls1x_eth1_pdev; | 22 | extern struct platform_device ls1x_eth1_pdev; |
20 | extern struct platform_device ls1x_ehci_pdev; | 23 | extern struct platform_device ls1x_ehci_pdev; |
24 | extern struct platform_device ls1x_gpio0_pdev; | ||
25 | extern struct platform_device ls1x_gpio1_pdev; | ||
26 | extern struct platform_device ls1x_nand_pdev; | ||
21 | extern struct platform_device ls1x_rtc_pdev; | 27 | extern struct platform_device ls1x_rtc_pdev; |
22 | 28 | ||
23 | extern void __init ls1x_clk_init(void); | 29 | void __init ls1x_clk_init(void); |
24 | extern void __init ls1x_serial_setup(struct platform_device *pdev); | 30 | void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata); |
31 | void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata); | ||
32 | void __init ls1x_serial_set_uartclk(struct platform_device *pdev); | ||
25 | 33 | ||
26 | #endif /* __ASM_MACH_LOONGSON32_PLATFORM_H */ | 34 | #endif /* __ASM_MACH_LOONGSON32_PLATFORM_H */ |
diff --git a/arch/mips/include/asm/mach-loongson32/regs-clk.h b/arch/mips/include/asm/mach-loongson32/regs-clk.h index 1f5a715ac841..4d56fc38f0c4 100644 --- a/arch/mips/include/asm/mach-loongson32/regs-clk.h +++ b/arch/mips/include/asm/mach-loongson32/regs-clk.h | |||
@@ -19,18 +19,18 @@ | |||
19 | #define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) | 19 | #define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) |
20 | 20 | ||
21 | /* Clock PLL Divisor Register Bits */ | 21 | /* Clock PLL Divisor Register Bits */ |
22 | #define DIV_DC_EN (0x1 << 31) | 22 | #define DIV_DC_EN BIT(31) |
23 | #define DIV_DC_RST (0x1 << 30) | 23 | #define DIV_DC_RST BIT(30) |
24 | #define DIV_CPU_EN (0x1 << 25) | 24 | #define DIV_CPU_EN BIT(25) |
25 | #define DIV_CPU_RST (0x1 << 24) | 25 | #define DIV_CPU_RST BIT(24) |
26 | #define DIV_DDR_EN (0x1 << 19) | 26 | #define DIV_DDR_EN BIT(19) |
27 | #define DIV_DDR_RST (0x1 << 18) | 27 | #define DIV_DDR_RST BIT(18) |
28 | #define RST_DC_EN (0x1 << 5) | 28 | #define RST_DC_EN BIT(5) |
29 | #define RST_DC (0x1 << 4) | 29 | #define RST_DC BIT(4) |
30 | #define RST_DDR_EN (0x1 << 3) | 30 | #define RST_DDR_EN BIT(3) |
31 | #define RST_DDR (0x1 << 2) | 31 | #define RST_DDR BIT(2) |
32 | #define RST_CPU_EN (0x1 << 1) | 32 | #define RST_CPU_EN BIT(1) |
33 | #define RST_CPU 0x1 | 33 | #define RST_CPU BIT(0) |
34 | 34 | ||
35 | #define DIV_DC_SHIFT 26 | 35 | #define DIV_DC_SHIFT 26 |
36 | #define DIV_CPU_SHIFT 20 | 36 | #define DIV_CPU_SHIFT 20 |
diff --git a/arch/mips/include/asm/mach-loongson32/regs-mux.h b/arch/mips/include/asm/mach-loongson32/regs-mux.h index 8302d92f2da2..7c394f93cb9e 100644 --- a/arch/mips/include/asm/mach-loongson32/regs-mux.h +++ b/arch/mips/include/asm/mach-loongson32/regs-mux.h | |||
@@ -19,49 +19,49 @@ | |||
19 | #define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) | 19 | #define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) |
20 | 20 | ||
21 | /* MUX CTRL0 Register Bits */ | 21 | /* MUX CTRL0 Register Bits */ |
22 | #define UART0_USE_PWM23 (0x1 << 28) | 22 | #define UART0_USE_PWM23 BIT(28) |
23 | #define UART0_USE_PWM01 (0x1 << 27) | 23 | #define UART0_USE_PWM01 BIT(27) |
24 | #define UART1_USE_LCD0_5_6_11 (0x1 << 26) | 24 | #define UART1_USE_LCD0_5_6_11 BIT(26) |
25 | #define I2C2_USE_CAN1 (0x1 << 25) | 25 | #define I2C2_USE_CAN1 BIT(25) |
26 | #define I2C1_USE_CAN0 (0x1 << 24) | 26 | #define I2C1_USE_CAN0 BIT(24) |
27 | #define NAND3_USE_UART5 (0x1 << 23) | 27 | #define NAND3_USE_UART5 BIT(23) |
28 | #define NAND3_USE_UART4 (0x1 << 22) | 28 | #define NAND3_USE_UART4 BIT(22) |
29 | #define NAND3_USE_UART1_DAT (0x1 << 21) | 29 | #define NAND3_USE_UART1_DAT BIT(21) |
30 | #define NAND3_USE_UART1_CTS (0x1 << 20) | 30 | #define NAND3_USE_UART1_CTS BIT(20) |
31 | #define NAND3_USE_PWM23 (0x1 << 19) | 31 | #define NAND3_USE_PWM23 BIT(19) |
32 | #define NAND3_USE_PWM01 (0x1 << 18) | 32 | #define NAND3_USE_PWM01 BIT(18) |
33 | #define NAND2_USE_UART5 (0x1 << 17) | 33 | #define NAND2_USE_UART5 BIT(17) |
34 | #define NAND2_USE_UART4 (0x1 << 16) | 34 | #define NAND2_USE_UART4 BIT(16) |
35 | #define NAND2_USE_UART1_DAT (0x1 << 15) | 35 | #define NAND2_USE_UART1_DAT BIT(15) |
36 | #define NAND2_USE_UART1_CTS (0x1 << 14) | 36 | #define NAND2_USE_UART1_CTS BIT(14) |
37 | #define NAND2_USE_PWM23 (0x1 << 13) | 37 | #define NAND2_USE_PWM23 BIT(13) |
38 | #define NAND2_USE_PWM01 (0x1 << 12) | 38 | #define NAND2_USE_PWM01 BIT(12) |
39 | #define NAND1_USE_UART5 (0x1 << 11) | 39 | #define NAND1_USE_UART5 BIT(11) |
40 | #define NAND1_USE_UART4 (0x1 << 10) | 40 | #define NAND1_USE_UART4 BIT(10) |
41 | #define NAND1_USE_UART1_DAT (0x1 << 9) | 41 | #define NAND1_USE_UART1_DAT BIT(9) |
42 | #define NAND1_USE_UART1_CTS (0x1 << 8) | 42 | #define NAND1_USE_UART1_CTS BIT(8) |
43 | #define NAND1_USE_PWM23 (0x1 << 7) | 43 | #define NAND1_USE_PWM23 BIT(7) |
44 | #define NAND1_USE_PWM01 (0x1 << 6) | 44 | #define NAND1_USE_PWM01 BIT(6) |
45 | #define GMAC1_USE_UART1 (0x1 << 4) | 45 | #define GMAC1_USE_UART1 BIT(4) |
46 | #define GMAC1_USE_UART0 (0x1 << 3) | 46 | #define GMAC1_USE_UART0 BIT(3) |
47 | #define LCD_USE_UART0_DAT (0x1 << 2) | 47 | #define LCD_USE_UART0_DAT BIT(2) |
48 | #define LCD_USE_UART15 (0x1 << 1) | 48 | #define LCD_USE_UART15 BIT(1) |
49 | #define LCD_USE_UART0 0x1 | 49 | #define LCD_USE_UART0 BIT(0) |
50 | 50 | ||
51 | /* MUX CTRL1 Register Bits */ | 51 | /* MUX CTRL1 Register Bits */ |
52 | #define USB_RESET (0x1 << 31) | 52 | #define USB_RESET BIT(31) |
53 | #define SPI1_CS_USE_PWM01 (0x1 << 24) | 53 | #define SPI1_CS_USE_PWM01 BIT(24) |
54 | #define SPI1_USE_CAN (0x1 << 23) | 54 | #define SPI1_USE_CAN BIT(23) |
55 | #define DISABLE_DDR_CONFSPACE (0x1 << 20) | 55 | #define DISABLE_DDR_CONFSPACE BIT(20) |
56 | #define DDR32TO16EN (0x1 << 16) | 56 | #define DDR32TO16EN BIT(16) |
57 | #define GMAC1_SHUT (0x1 << 13) | 57 | #define GMAC1_SHUT BIT(13) |
58 | #define GMAC0_SHUT (0x1 << 12) | 58 | #define GMAC0_SHUT BIT(12) |
59 | #define USB_SHUT (0x1 << 11) | 59 | #define USB_SHUT BIT(11) |
60 | #define UART1_3_USE_CAN1 (0x1 << 5) | 60 | #define UART1_3_USE_CAN1 BIT(5) |
61 | #define UART1_2_USE_CAN0 (0x1 << 4) | 61 | #define UART1_2_USE_CAN0 BIT(4) |
62 | #define GMAC1_USE_TXCLK (0x1 << 3) | 62 | #define GMAC1_USE_TXCLK BIT(3) |
63 | #define GMAC0_USE_TXCLK (0x1 << 2) | 63 | #define GMAC0_USE_TXCLK BIT(2) |
64 | #define GMAC1_USE_PWM23 (0x1 << 1) | 64 | #define GMAC1_USE_PWM23 BIT(1) |
65 | #define GMAC0_USE_PWM01 0x1 | 65 | #define GMAC0_USE_PWM01 BIT(0) |
66 | 66 | ||
67 | #endif /* __ASM_MACH_LOONGSON32_REGS_MUX_H */ | 67 | #endif /* __ASM_MACH_LOONGSON32_REGS_MUX_H */ |
diff --git a/arch/mips/include/asm/mach-loongson32/regs-pwm.h b/arch/mips/include/asm/mach-loongson32/regs-pwm.h index 69f174ed13a4..4119600ce79a 100644 --- a/arch/mips/include/asm/mach-loongson32/regs-pwm.h +++ b/arch/mips/include/asm/mach-loongson32/regs-pwm.h | |||
@@ -19,11 +19,11 @@ | |||
19 | #define PWM_CTRL 0xc | 19 | #define PWM_CTRL 0xc |
20 | 20 | ||
21 | /* PWM Control Register Bits */ | 21 | /* PWM Control Register Bits */ |
22 | #define CNT_RST (0x1 << 7) | 22 | #define CNT_RST BIT(7) |
23 | #define INT_SR (0x1 << 6) | 23 | #define INT_SR BIT(6) |
24 | #define INT_EN (0x1 << 5) | 24 | #define INT_EN BIT(5) |
25 | #define PWM_SINGLE (0x1 << 4) | 25 | #define PWM_SINGLE BIT(4) |
26 | #define PWM_OE (0x1 << 3) | 26 | #define PWM_OE BIT(3) |
27 | #define CNT_EN 0x1 | 27 | #define CNT_EN BIT(0) |
28 | 28 | ||
29 | #endif /* __ASM_MACH_LOONGSON32_REGS_PWM_H */ | 29 | #endif /* __ASM_MACH_LOONGSON32_REGS_PWM_H */ |
diff --git a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h index 98963c2c7be4..89328a3d44d8 100644 --- a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h | |||
@@ -16,11 +16,6 @@ | |||
16 | #ifndef __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H | 16 | #ifndef __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H |
17 | #define __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H | 17 | #define __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H |
18 | 18 | ||
19 | #define cpu_dcache_line_size() 32 | ||
20 | #define cpu_icache_line_size() 32 | ||
21 | #define cpu_scache_line_size() 32 | ||
22 | |||
23 | |||
24 | #define cpu_has_32fpr 1 | 19 | #define cpu_has_32fpr 1 |
25 | #define cpu_has_3k_cache 0 | 20 | #define cpu_has_3k_cache 0 |
26 | #define cpu_has_4k_cache 1 | 21 | #define cpu_has_4k_cache 1 |
@@ -31,24 +26,17 @@ | |||
31 | #define cpu_has_counter 1 | 26 | #define cpu_has_counter 1 |
32 | #define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) | 27 | #define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) |
33 | #define cpu_has_divec 0 | 28 | #define cpu_has_divec 0 |
34 | #define cpu_has_dsp 0 | ||
35 | #define cpu_has_dsp2 0 | ||
36 | #define cpu_has_ejtag 0 | 29 | #define cpu_has_ejtag 0 |
37 | #define cpu_has_ic_fills_f_dc 0 | ||
38 | #define cpu_has_inclusive_pcaches 1 | 30 | #define cpu_has_inclusive_pcaches 1 |
39 | #define cpu_has_llsc 1 | 31 | #define cpu_has_llsc 1 |
40 | #define cpu_has_mcheck 0 | 32 | #define cpu_has_mcheck 0 |
41 | #define cpu_has_mdmx 0 | 33 | #define cpu_has_mdmx 0 |
42 | #define cpu_has_mips16 0 | 34 | #define cpu_has_mips16 0 |
43 | #define cpu_has_mips32r2 0 | ||
44 | #define cpu_has_mips3d 0 | 35 | #define cpu_has_mips3d 0 |
45 | #define cpu_has_mips64r2 0 | ||
46 | #define cpu_has_mipsmt 0 | 36 | #define cpu_has_mipsmt 0 |
47 | #define cpu_has_prefetch 0 | ||
48 | #define cpu_has_smartmips 0 | 37 | #define cpu_has_smartmips 0 |
49 | #define cpu_has_tlb 1 | 38 | #define cpu_has_tlb 1 |
50 | #define cpu_has_tx39_cache 0 | 39 | #define cpu_has_tx39_cache 0 |
51 | #define cpu_has_userlocal 0 | ||
52 | #define cpu_has_vce 0 | 40 | #define cpu_has_vce 0 |
53 | #define cpu_has_veic 0 | 41 | #define cpu_has_veic 0 |
54 | #define cpu_has_vint 0 | 42 | #define cpu_has_vint 0 |
@@ -56,6 +44,10 @@ | |||
56 | #define cpu_has_watch 1 | 44 | #define cpu_has_watch 1 |
57 | #define cpu_has_local_ebase 0 | 45 | #define cpu_has_local_ebase 0 |
58 | 46 | ||
59 | #define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) | 47 | #ifdef CONFIG_CPU_LOONGSON3 |
48 | #define cpu_has_wsbh 1 | ||
49 | #define cpu_has_ic_fills_f_dc 1 | ||
50 | #define cpu_hwrena_impl_bits 0xc0000000 | ||
51 | #endif | ||
60 | 52 | ||
61 | #endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */ | 53 | #endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */ |
diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h index 3f2f84f6c401..8393bc548987 100644 --- a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h | |||
@@ -23,8 +23,15 @@ | |||
23 | or t0, (0x1 << 7) | 23 | or t0, (0x1 << 7) |
24 | mtc0 t0, $16, 3 | 24 | mtc0 t0, $16, 3 |
25 | /* Set ELPA on LOONGSON3 pagegrain */ | 25 | /* Set ELPA on LOONGSON3 pagegrain */ |
26 | li t0, (0x1 << 29) | 26 | mfc0 t0, $5, 1 |
27 | or t0, (0x1 << 29) | ||
27 | mtc0 t0, $5, 1 | 28 | mtc0 t0, $5, 1 |
29 | #ifdef CONFIG_LOONGSON3_ENHANCEMENT | ||
30 | /* Enable STFill Buffer */ | ||
31 | mfc0 t0, $16, 6 | ||
32 | or t0, 0x100 | ||
33 | mtc0 t0, $16, 6 | ||
34 | #endif | ||
28 | _ehb | 35 | _ehb |
29 | .set pop | 36 | .set pop |
30 | #endif | 37 | #endif |
@@ -42,8 +49,15 @@ | |||
42 | or t0, (0x1 << 7) | 49 | or t0, (0x1 << 7) |
43 | mtc0 t0, $16, 3 | 50 | mtc0 t0, $16, 3 |
44 | /* Set ELPA on LOONGSON3 pagegrain */ | 51 | /* Set ELPA on LOONGSON3 pagegrain */ |
45 | li t0, (0x1 << 29) | 52 | mfc0 t0, $5, 1 |
53 | or t0, (0x1 << 29) | ||
46 | mtc0 t0, $5, 1 | 54 | mtc0 t0, $5, 1 |
55 | #ifdef CONFIG_LOONGSON3_ENHANCEMENT | ||
56 | /* Enable STFill Buffer */ | ||
57 | mfc0 t0, $16, 6 | ||
58 | or t0, 0x100 | ||
59 | mtc0 t0, $16, 6 | ||
60 | #endif | ||
47 | _ehb | 61 | _ehb |
48 | .set pop | 62 | .set pop |
49 | #endif | 63 | #endif |
diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h index 455d406e8ddf..a73350b07fdf 100644 --- a/arch/mips/include/asm/mach-ralink/mt7620.h +++ b/arch/mips/include/asm/mach-ralink/mt7620.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 10 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _MT7620_REGS_H_ | 13 | #ifndef _MT7620_REGS_H_ |
@@ -72,6 +72,7 @@ | |||
72 | #define SYSCFG0_DRAM_TYPE_SDRAM 0 | 72 | #define SYSCFG0_DRAM_TYPE_SDRAM 0 |
73 | #define SYSCFG0_DRAM_TYPE_DDR1 1 | 73 | #define SYSCFG0_DRAM_TYPE_DDR1 1 |
74 | #define SYSCFG0_DRAM_TYPE_DDR2 2 | 74 | #define SYSCFG0_DRAM_TYPE_DDR2 2 |
75 | #define SYSCFG0_DRAM_TYPE_UNKNOWN 3 | ||
75 | 76 | ||
76 | #define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0 | 77 | #define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0 |
77 | #define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1 | 78 | #define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1 |
diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h index 610b61e3f9df..a672e06fa5fd 100644 --- a/arch/mips/include/asm/mach-ralink/mt7621.h +++ b/arch/mips/include/asm/mach-ralink/mt7621.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2015 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _MT7621_REGS_H_ | 9 | #ifndef _MT7621_REGS_H_ |
diff --git a/arch/mips/include/asm/mach-ralink/pinmux.h b/arch/mips/include/asm/mach-ralink/pinmux.h index be106cb2e26d..ba8ac331af0c 100644 --- a/arch/mips/include/asm/mach-ralink/pinmux.h +++ b/arch/mips/include/asm/mach-ralink/pinmux.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * it under the terms of the GNU General Public License version 2 as | 3 | * it under the terms of the GNU General Public License version 2 as |
4 | * publishhed by the Free Software Foundation. | 4 | * publishhed by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _RT288X_PINMUX_H__ | 9 | #ifndef _RT288X_PINMUX_H__ |
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h index 4c9fba68c8b2..9df1a53bcb36 100644 --- a/arch/mips/include/asm/mach-ralink/ralink_regs.h +++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Ralink SoC register definitions | 2 | * Ralink SoC register definitions |
3 | * | 3 | * |
4 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 4 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
5 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | 5 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> |
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
7 | * | 7 | * |
diff --git a/arch/mips/include/asm/mach-ralink/rt288x.h b/arch/mips/include/asm/mach-ralink/rt288x.h index 03ad716acb42..25ae1042d57b 100644 --- a/arch/mips/include/asm/mach-ralink/rt288x.h +++ b/arch/mips/include/asm/mach-ralink/rt288x.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 10 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _RT288X_REGS_H_ | 13 | #ifndef _RT288X_REGS_H_ |
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h index 2eea79331a14..ac2d65c04b5f 100644 --- a/arch/mips/include/asm/mach-ralink/rt305x.h +++ b/arch/mips/include/asm/mach-ralink/rt305x.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 10 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _RT305X_REGS_H_ | 13 | #ifndef _RT305X_REGS_H_ |
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index d4635391c36a..9411a4c0bdad 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h | |||
@@ -208,6 +208,7 @@ BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130) | |||
208 | BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150) | 208 | BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150) |
209 | BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300) | 209 | BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300) |
210 | BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308) | 210 | BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308) |
211 | BUILD_CM_RW(bev_base, MIPS_CM_GCB_OFS + 0x680) | ||
211 | 212 | ||
212 | /* Core Local & Core Other register accessor functions */ | 213 | /* Core Local & Core Other register accessor functions */ |
213 | BUILD_CM_Cx_RW(reset_release, 0x00) | 214 | BUILD_CM_Cx_RW(reset_release, 0x00) |
@@ -290,8 +291,8 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) | |||
290 | #define CM_GCR_GIC_BASE_GICEN_MSK (_ULCAST_(0x1) << 0) | 291 | #define CM_GCR_GIC_BASE_GICEN_MSK (_ULCAST_(0x1) << 0) |
291 | 292 | ||
292 | /* GCR_CPC_BASE register fields */ | 293 | /* GCR_CPC_BASE register fields */ |
293 | #define CM_GCR_CPC_BASE_CPCBASE_SHF 17 | 294 | #define CM_GCR_CPC_BASE_CPCBASE_SHF 15 |
294 | #define CM_GCR_CPC_BASE_CPCBASE_MSK (_ULCAST_(0x7fff) << 17) | 295 | #define CM_GCR_CPC_BASE_CPCBASE_MSK (_ULCAST_(0x1ffff) << 15) |
295 | #define CM_GCR_CPC_BASE_CPCEN_SHF 0 | 296 | #define CM_GCR_CPC_BASE_CPCEN_SHF 0 |
296 | #define CM_GCR_CPC_BASE_CPCEN_MSK (_ULCAST_(0x1) << 0) | 297 | #define CM_GCR_CPC_BASE_CPCEN_MSK (_ULCAST_(0x1) << 0) |
297 | 298 | ||
@@ -461,7 +462,10 @@ static inline unsigned int mips_cm_max_vp_width(void) | |||
461 | if (mips_cm_revision() >= CM_REV_CM3) | 462 | if (mips_cm_revision() >= CM_REV_CM3) |
462 | return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW_MSK; | 463 | return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW_MSK; |
463 | 464 | ||
464 | return smp_num_siblings; | 465 | if (config_enabled(CONFIG_SMP)) |
466 | return smp_num_siblings; | ||
467 | |||
468 | return 1; | ||
465 | } | 469 | } |
466 | 470 | ||
467 | /** | 471 | /** |
@@ -505,7 +509,7 @@ extern void mips_cm_unlock_other(void); | |||
505 | 509 | ||
506 | #else /* !CONFIG_MIPS_CM */ | 510 | #else /* !CONFIG_MIPS_CM */ |
507 | 511 | ||
508 | static inline void mips_cm_lock_other(unsigned int core) { } | 512 | static inline void mips_cm_lock_other(unsigned int core, unsigned int vp) { } |
509 | static inline void mips_cm_unlock_other(void) { } | 513 | static inline void mips_cm_unlock_other(void) { } |
510 | 514 | ||
511 | #endif /* !CONFIG_MIPS_CM */ | 515 | #endif /* !CONFIG_MIPS_CM */ |
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h index e09035239e53..8c519f9827a3 100644 --- a/arch/mips/include/asm/mips-cpc.h +++ b/arch/mips/include/asm/mips-cpc.h | |||
@@ -106,6 +106,9 @@ BUILD_CPC_R_(revision, MIPS_CPC_GCB_OFS + 0x20) | |||
106 | BUILD_CPC_Cx_RW(cmd, 0x00) | 106 | BUILD_CPC_Cx_RW(cmd, 0x00) |
107 | BUILD_CPC_Cx_RW(stat_conf, 0x08) | 107 | BUILD_CPC_Cx_RW(stat_conf, 0x08) |
108 | BUILD_CPC_Cx_RW(other, 0x10) | 108 | BUILD_CPC_Cx_RW(other, 0x10) |
109 | BUILD_CPC_Cx_RW(vp_stop, 0x20) | ||
110 | BUILD_CPC_Cx_RW(vp_run, 0x28) | ||
111 | BUILD_CPC_Cx_RW(vp_running, 0x30) | ||
109 | 112 | ||
110 | /* CPC_Cx_CMD register fields */ | 113 | /* CPC_Cx_CMD register fields */ |
111 | #define CPC_Cx_CMD_SHF 0 | 114 | #define CPC_Cx_CMD_SHF 0 |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 3ad19ad04d8a..25d01577d0b5 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -55,8 +55,14 @@ | |||
55 | #define CP0_BADINSTR $8, 1 | 55 | #define CP0_BADINSTR $8, 1 |
56 | #define CP0_COUNT $9 | 56 | #define CP0_COUNT $9 |
57 | #define CP0_ENTRYHI $10 | 57 | #define CP0_ENTRYHI $10 |
58 | #define CP0_GUESTCTL1 $10, 4 | ||
59 | #define CP0_GUESTCTL2 $10, 5 | ||
60 | #define CP0_GUESTCTL3 $10, 6 | ||
58 | #define CP0_COMPARE $11 | 61 | #define CP0_COMPARE $11 |
62 | #define CP0_GUESTCTL0EXT $11, 4 | ||
59 | #define CP0_STATUS $12 | 63 | #define CP0_STATUS $12 |
64 | #define CP0_GUESTCTL0 $12, 6 | ||
65 | #define CP0_GTOFFSET $12, 7 | ||
60 | #define CP0_CAUSE $13 | 66 | #define CP0_CAUSE $13 |
61 | #define CP0_EPC $14 | 67 | #define CP0_EPC $14 |
62 | #define CP0_PRID $15 | 68 | #define CP0_PRID $15 |
@@ -229,6 +235,8 @@ | |||
229 | 235 | ||
230 | /* MIPS32/64 EntryHI bit definitions */ | 236 | /* MIPS32/64 EntryHI bit definitions */ |
231 | #define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10) | 237 | #define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10) |
238 | #define MIPS_ENTRYHI_ASIDX (_ULCAST_(0x3) << 8) | ||
239 | #define MIPS_ENTRYHI_ASID (_ULCAST_(0xff) << 0) | ||
232 | 240 | ||
233 | /* | 241 | /* |
234 | * R4x00 interrupt enable / cause bits | 242 | * R4x00 interrupt enable / cause bits |
@@ -390,6 +398,8 @@ | |||
390 | #define CAUSEF_IP7 (_ULCAST_(1) << 15) | 398 | #define CAUSEF_IP7 (_ULCAST_(1) << 15) |
391 | #define CAUSEB_FDCI 21 | 399 | #define CAUSEB_FDCI 21 |
392 | #define CAUSEF_FDCI (_ULCAST_(1) << 21) | 400 | #define CAUSEF_FDCI (_ULCAST_(1) << 21) |
401 | #define CAUSEB_WP 22 | ||
402 | #define CAUSEF_WP (_ULCAST_(1) << 22) | ||
393 | #define CAUSEB_IV 23 | 403 | #define CAUSEB_IV 23 |
394 | #define CAUSEF_IV (_ULCAST_(1) << 23) | 404 | #define CAUSEF_IV (_ULCAST_(1) << 23) |
395 | #define CAUSEB_PCI 26 | 405 | #define CAUSEB_PCI 26 |
@@ -611,7 +621,8 @@ | |||
611 | #define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14) | 621 | #define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14) |
612 | #define MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT (_ULCAST_(2) << 14) | 622 | #define MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT (_ULCAST_(2) << 14) |
613 | #define MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT (_ULCAST_(3) << 14) | 623 | #define MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT (_ULCAST_(3) << 14) |
614 | #define MIPS_CONF4_KSCREXIST (_ULCAST_(255) << 16) | 624 | #define MIPS_CONF4_KSCREXIST_SHIFT (16) |
625 | #define MIPS_CONF4_KSCREXIST (_ULCAST_(255) << MIPS_CONF4_KSCREXIST_SHIFT) | ||
615 | #define MIPS_CONF4_VTLBSIZEEXT_SHIFT (24) | 626 | #define MIPS_CONF4_VTLBSIZEEXT_SHIFT (24) |
616 | #define MIPS_CONF4_VTLBSIZEEXT (_ULCAST_(15) << MIPS_CONF4_VTLBSIZEEXT_SHIFT) | 627 | #define MIPS_CONF4_VTLBSIZEEXT (_ULCAST_(15) << MIPS_CONF4_VTLBSIZEEXT_SHIFT) |
617 | #define MIPS_CONF4_AE (_ULCAST_(1) << 28) | 628 | #define MIPS_CONF4_AE (_ULCAST_(1) << 28) |
@@ -623,6 +634,7 @@ | |||
623 | #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) | 634 | #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) |
624 | #define MIPS_CONF5_LLB (_ULCAST_(1) << 4) | 635 | #define MIPS_CONF5_LLB (_ULCAST_(1) << 4) |
625 | #define MIPS_CONF5_MVH (_ULCAST_(1) << 5) | 636 | #define MIPS_CONF5_MVH (_ULCAST_(1) << 5) |
637 | #define MIPS_CONF5_VP (_ULCAST_(1) << 7) | ||
626 | #define MIPS_CONF5_FRE (_ULCAST_(1) << 8) | 638 | #define MIPS_CONF5_FRE (_ULCAST_(1) << 8) |
627 | #define MIPS_CONF5_UFE (_ULCAST_(1) << 9) | 639 | #define MIPS_CONF5_UFE (_ULCAST_(1) << 9) |
628 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) | 640 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) |
@@ -633,6 +645,8 @@ | |||
633 | #define MIPS_CONF6_SYND (_ULCAST_(1) << 13) | 645 | #define MIPS_CONF6_SYND (_ULCAST_(1) << 13) |
634 | /* proAptiv FTLB on/off bit */ | 646 | /* proAptiv FTLB on/off bit */ |
635 | #define MIPS_CONF6_FTLBEN (_ULCAST_(1) << 15) | 647 | #define MIPS_CONF6_FTLBEN (_ULCAST_(1) << 15) |
648 | /* Loongson-3 FTLB on/off bit */ | ||
649 | #define MIPS_CONF6_FTLBDIS (_ULCAST_(1) << 22) | ||
636 | /* FTLB probability bits */ | 650 | /* FTLB probability bits */ |
637 | #define MIPS_CONF6_FTLBP_SHIFT (16) | 651 | #define MIPS_CONF6_FTLBP_SHIFT (16) |
638 | 652 | ||
@@ -645,12 +659,38 @@ | |||
645 | /* FTLB probability bits for R6 */ | 659 | /* FTLB probability bits for R6 */ |
646 | #define MIPS_CONF7_FTLBP_SHIFT (18) | 660 | #define MIPS_CONF7_FTLBP_SHIFT (18) |
647 | 661 | ||
662 | /* WatchLo* register definitions */ | ||
663 | #define MIPS_WATCHLO_IRW (_ULCAST_(0x7) << 0) | ||
664 | |||
665 | /* WatchHi* register definitions */ | ||
666 | #define MIPS_WATCHHI_M (_ULCAST_(1) << 31) | ||
667 | #define MIPS_WATCHHI_G (_ULCAST_(1) << 30) | ||
668 | #define MIPS_WATCHHI_WM (_ULCAST_(0x3) << 28) | ||
669 | #define MIPS_WATCHHI_WM_R_RVA (_ULCAST_(0) << 28) | ||
670 | #define MIPS_WATCHHI_WM_R_GPA (_ULCAST_(1) << 28) | ||
671 | #define MIPS_WATCHHI_WM_G_GVA (_ULCAST_(2) << 28) | ||
672 | #define MIPS_WATCHHI_EAS (_ULCAST_(0x3) << 24) | ||
673 | #define MIPS_WATCHHI_ASID (_ULCAST_(0xff) << 16) | ||
674 | #define MIPS_WATCHHI_MASK (_ULCAST_(0x1ff) << 3) | ||
675 | #define MIPS_WATCHHI_I (_ULCAST_(1) << 2) | ||
676 | #define MIPS_WATCHHI_R (_ULCAST_(1) << 1) | ||
677 | #define MIPS_WATCHHI_W (_ULCAST_(1) << 0) | ||
678 | #define MIPS_WATCHHI_IRW (_ULCAST_(0x7) << 0) | ||
679 | |||
648 | /* MAAR bit definitions */ | 680 | /* MAAR bit definitions */ |
649 | #define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) | 681 | #define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) |
650 | #define MIPS_MAAR_ADDR_SHIFT 12 | 682 | #define MIPS_MAAR_ADDR_SHIFT 12 |
651 | #define MIPS_MAAR_S (_ULCAST_(1) << 1) | 683 | #define MIPS_MAAR_S (_ULCAST_(1) << 1) |
652 | #define MIPS_MAAR_V (_ULCAST_(1) << 0) | 684 | #define MIPS_MAAR_V (_ULCAST_(1) << 0) |
653 | 685 | ||
686 | /* EBase bit definitions */ | ||
687 | #define MIPS_EBASE_CPUNUM_SHIFT 0 | ||
688 | #define MIPS_EBASE_CPUNUM (_ULCAST_(0x3ff) << 0) | ||
689 | #define MIPS_EBASE_WG_SHIFT 11 | ||
690 | #define MIPS_EBASE_WG (_ULCAST_(1) << 11) | ||
691 | #define MIPS_EBASE_BASE_SHIFT 12 | ||
692 | #define MIPS_EBASE_BASE (~_ULCAST_((1 << MIPS_EBASE_BASE_SHIFT) - 1)) | ||
693 | |||
654 | /* CMGCRBase bit definitions */ | 694 | /* CMGCRBase bit definitions */ |
655 | #define MIPS_CMGCRB_BASE 11 | 695 | #define MIPS_CMGCRB_BASE 11 |
656 | #define MIPS_CMGCRF_BASE (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1)) | 696 | #define MIPS_CMGCRF_BASE (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1)) |
@@ -706,6 +746,94 @@ | |||
706 | #define MIPS_PWCTL_PSN_SHIFT 0 | 746 | #define MIPS_PWCTL_PSN_SHIFT 0 |
707 | #define MIPS_PWCTL_PSN_MASK 0x0000003f | 747 | #define MIPS_PWCTL_PSN_MASK 0x0000003f |
708 | 748 | ||
749 | /* GuestCtl0 fields */ | ||
750 | #define MIPS_GCTL0_GM_SHIFT 31 | ||
751 | #define MIPS_GCTL0_GM (_ULCAST_(1) << MIPS_GCTL0_GM_SHIFT) | ||
752 | #define MIPS_GCTL0_RI_SHIFT 30 | ||
753 | #define MIPS_GCTL0_RI (_ULCAST_(1) << MIPS_GCTL0_RI_SHIFT) | ||
754 | #define MIPS_GCTL0_MC_SHIFT 29 | ||
755 | #define MIPS_GCTL0_MC (_ULCAST_(1) << MIPS_GCTL0_MC_SHIFT) | ||
756 | #define MIPS_GCTL0_CP0_SHIFT 28 | ||
757 | #define MIPS_GCTL0_CP0 (_ULCAST_(1) << MIPS_GCTL0_CP0_SHIFT) | ||
758 | #define MIPS_GCTL0_AT_SHIFT 26 | ||
759 | #define MIPS_GCTL0_AT (_ULCAST_(0x3) << MIPS_GCTL0_AT_SHIFT) | ||
760 | #define MIPS_GCTL0_GT_SHIFT 25 | ||
761 | #define MIPS_GCTL0_GT (_ULCAST_(1) << MIPS_GCTL0_GT_SHIFT) | ||
762 | #define MIPS_GCTL0_CG_SHIFT 24 | ||
763 | #define MIPS_GCTL0_CG (_ULCAST_(1) << MIPS_GCTL0_CG_SHIFT) | ||
764 | #define MIPS_GCTL0_CF_SHIFT 23 | ||
765 | #define MIPS_GCTL0_CF (_ULCAST_(1) << MIPS_GCTL0_CF_SHIFT) | ||
766 | #define MIPS_GCTL0_G1_SHIFT 22 | ||
767 | #define MIPS_GCTL0_G1 (_ULCAST_(1) << MIPS_GCTL0_G1_SHIFT) | ||
768 | #define MIPS_GCTL0_G0E_SHIFT 19 | ||
769 | #define MIPS_GCTL0_G0E (_ULCAST_(1) << MIPS_GCTL0_G0E_SHIFT) | ||
770 | #define MIPS_GCTL0_PT_SHIFT 18 | ||
771 | #define MIPS_GCTL0_PT (_ULCAST_(1) << MIPS_GCTL0_PT_SHIFT) | ||
772 | #define MIPS_GCTL0_RAD_SHIFT 9 | ||
773 | #define MIPS_GCTL0_RAD (_ULCAST_(1) << MIPS_GCTL0_RAD_SHIFT) | ||
774 | #define MIPS_GCTL0_DRG_SHIFT 8 | ||
775 | #define MIPS_GCTL0_DRG (_ULCAST_(1) << MIPS_GCTL0_DRG_SHIFT) | ||
776 | #define MIPS_GCTL0_G2_SHIFT 7 | ||
777 | #define MIPS_GCTL0_G2 (_ULCAST_(1) << MIPS_GCTL0_G2_SHIFT) | ||
778 | #define MIPS_GCTL0_GEXC_SHIFT 2 | ||
779 | #define MIPS_GCTL0_GEXC (_ULCAST_(0x1f) << MIPS_GCTL0_GEXC_SHIFT) | ||
780 | #define MIPS_GCTL0_SFC2_SHIFT 1 | ||
781 | #define MIPS_GCTL0_SFC2 (_ULCAST_(1) << MIPS_GCTL0_SFC2_SHIFT) | ||
782 | #define MIPS_GCTL0_SFC1_SHIFT 0 | ||
783 | #define MIPS_GCTL0_SFC1 (_ULCAST_(1) << MIPS_GCTL0_SFC1_SHIFT) | ||
784 | |||
785 | /* GuestCtl0.AT Guest address translation control */ | ||
786 | #define MIPS_GCTL0_AT_ROOT 1 /* Guest MMU under Root control */ | ||
787 | #define MIPS_GCTL0_AT_GUEST 3 /* Guest MMU under Guest control */ | ||
788 | |||
789 | /* GuestCtl0.GExcCode Hypervisor exception cause codes */ | ||
790 | #define MIPS_GCTL0_GEXC_GPSI 0 /* Guest Privileged Sensitive Instruction */ | ||
791 | #define MIPS_GCTL0_GEXC_GSFC 1 /* Guest Software Field Change */ | ||
792 | #define MIPS_GCTL0_GEXC_HC 2 /* Hypercall */ | ||
793 | #define MIPS_GCTL0_GEXC_GRR 3 /* Guest Reserved Instruction Redirect */ | ||
794 | #define MIPS_GCTL0_GEXC_GVA 8 /* Guest Virtual Address available */ | ||
795 | #define MIPS_GCTL0_GEXC_GHFC 9 /* Guest Hardware Field Change */ | ||
796 | #define MIPS_GCTL0_GEXC_GPA 10 /* Guest Physical Address available */ | ||
797 | |||
798 | /* GuestCtl0Ext fields */ | ||
799 | #define MIPS_GCTL0EXT_RPW_SHIFT 8 | ||
800 | #define MIPS_GCTL0EXT_RPW (_ULCAST_(0x3) << MIPS_GCTL0EXT_RPW_SHIFT) | ||
801 | #define MIPS_GCTL0EXT_NCC_SHIFT 6 | ||
802 | #define MIPS_GCTL0EXT_NCC (_ULCAST_(0x3) << MIPS_GCTL0EXT_NCC_SHIFT) | ||
803 | #define MIPS_GCTL0EXT_CGI_SHIFT 4 | ||
804 | #define MIPS_GCTL0EXT_CGI (_ULCAST_(1) << MIPS_GCTL0EXT_CGI_SHIFT) | ||
805 | #define MIPS_GCTL0EXT_FCD_SHIFT 3 | ||
806 | #define MIPS_GCTL0EXT_FCD (_ULCAST_(1) << MIPS_GCTL0EXT_FCD_SHIFT) | ||
807 | #define MIPS_GCTL0EXT_OG_SHIFT 2 | ||
808 | #define MIPS_GCTL0EXT_OG (_ULCAST_(1) << MIPS_GCTL0EXT_OG_SHIFT) | ||
809 | #define MIPS_GCTL0EXT_BG_SHIFT 1 | ||
810 | #define MIPS_GCTL0EXT_BG (_ULCAST_(1) << MIPS_GCTL0EXT_BG_SHIFT) | ||
811 | #define MIPS_GCTL0EXT_MG_SHIFT 0 | ||
812 | #define MIPS_GCTL0EXT_MG (_ULCAST_(1) << MIPS_GCTL0EXT_MG_SHIFT) | ||
813 | |||
814 | /* GuestCtl0Ext.RPW Root page walk configuration */ | ||
815 | #define MIPS_GCTL0EXT_RPW_BOTH 0 /* Root PW for GPA->RPA and RVA->RPA */ | ||
816 | #define MIPS_GCTL0EXT_RPW_GPA 2 /* Root PW for GPA->RPA */ | ||
817 | #define MIPS_GCTL0EXT_RPW_RVA 3 /* Root PW for RVA->RPA */ | ||
818 | |||
819 | /* GuestCtl0Ext.NCC Nested cache coherency attributes */ | ||
820 | #define MIPS_GCTL0EXT_NCC_IND 0 /* Guest CCA independent of Root CCA */ | ||
821 | #define MIPS_GCTL0EXT_NCC_MOD 1 /* Guest CCA modified by Root CCA */ | ||
822 | |||
823 | /* GuestCtl1 fields */ | ||
824 | #define MIPS_GCTL1_ID_SHIFT 0 | ||
825 | #define MIPS_GCTL1_ID_WIDTH 8 | ||
826 | #define MIPS_GCTL1_ID (_ULCAST_(0xff) << MIPS_GCTL1_ID_SHIFT) | ||
827 | #define MIPS_GCTL1_RID_SHIFT 16 | ||
828 | #define MIPS_GCTL1_RID_WIDTH 8 | ||
829 | #define MIPS_GCTL1_RID (_ULCAST_(0xff) << MIPS_GCTL1_RID_SHIFT) | ||
830 | #define MIPS_GCTL1_EID_SHIFT 24 | ||
831 | #define MIPS_GCTL1_EID_WIDTH 8 | ||
832 | #define MIPS_GCTL1_EID (_ULCAST_(0xff) << MIPS_GCTL1_EID_SHIFT) | ||
833 | |||
834 | /* GuestID reserved for root context */ | ||
835 | #define MIPS_GCTL1_ROOT_GUESTID 0 | ||
836 | |||
709 | /* CDMMBase register bit definitions */ | 837 | /* CDMMBase register bit definitions */ |
710 | #define MIPS_CDMMBASE_SIZE_SHIFT 0 | 838 | #define MIPS_CDMMBASE_SIZE_SHIFT 0 |
711 | #define MIPS_CDMMBASE_SIZE (_ULCAST_(511) << MIPS_CDMMBASE_SIZE_SHIFT) | 839 | #define MIPS_CDMMBASE_SIZE (_ULCAST_(511) << MIPS_CDMMBASE_SIZE_SHIFT) |
@@ -757,6 +885,15 @@ | |||
757 | /* Disable Branch Return Cache */ | 885 | /* Disable Branch Return Cache */ |
758 | #define R10K_DIAG_D_BRC (_ULCAST_(1) << 22) | 886 | #define R10K_DIAG_D_BRC (_ULCAST_(1) << 22) |
759 | 887 | ||
888 | /* Flush ITLB */ | ||
889 | #define LOONGSON_DIAG_ITLB (_ULCAST_(1) << 2) | ||
890 | /* Flush DTLB */ | ||
891 | #define LOONGSON_DIAG_DTLB (_ULCAST_(1) << 3) | ||
892 | /* Flush VTLB */ | ||
893 | #define LOONGSON_DIAG_VTLB (_ULCAST_(1) << 12) | ||
894 | /* Flush FTLB */ | ||
895 | #define LOONGSON_DIAG_FTLB (_ULCAST_(1) << 13) | ||
896 | |||
760 | /* | 897 | /* |
761 | * Coprocessor 1 (FPU) register names | 898 | * Coprocessor 1 (FPU) register names |
762 | */ | 899 | */ |
@@ -1186,9 +1323,15 @@ do { \ | |||
1186 | #define read_c0_context() __read_ulong_c0_register($4, 0) | 1323 | #define read_c0_context() __read_ulong_c0_register($4, 0) |
1187 | #define write_c0_context(val) __write_ulong_c0_register($4, 0, val) | 1324 | #define write_c0_context(val) __write_ulong_c0_register($4, 0, val) |
1188 | 1325 | ||
1326 | #define read_c0_contextconfig() __read_32bit_c0_register($4, 1) | ||
1327 | #define write_c0_contextconfig(val) __write_32bit_c0_register($4, 1, val) | ||
1328 | |||
1189 | #define read_c0_userlocal() __read_ulong_c0_register($4, 2) | 1329 | #define read_c0_userlocal() __read_ulong_c0_register($4, 2) |
1190 | #define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) | 1330 | #define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) |
1191 | 1331 | ||
1332 | #define read_c0_xcontextconfig() __read_ulong_c0_register($4, 3) | ||
1333 | #define write_c0_xcontextconfig(val) __write_ulong_c0_register($4, 3, val) | ||
1334 | |||
1192 | #define read_c0_pagemask() __read_32bit_c0_register($5, 0) | 1335 | #define read_c0_pagemask() __read_32bit_c0_register($5, 0) |
1193 | #define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) | 1336 | #define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) |
1194 | 1337 | ||
@@ -1206,6 +1349,9 @@ do { \ | |||
1206 | #define read_c0_badvaddr() __read_ulong_c0_register($8, 0) | 1349 | #define read_c0_badvaddr() __read_ulong_c0_register($8, 0) |
1207 | #define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) | 1350 | #define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) |
1208 | 1351 | ||
1352 | #define read_c0_badinstr() __read_32bit_c0_register($8, 1) | ||
1353 | #define read_c0_badinstrp() __read_32bit_c0_register($8, 2) | ||
1354 | |||
1209 | #define read_c0_count() __read_32bit_c0_register($9, 0) | 1355 | #define read_c0_count() __read_32bit_c0_register($9, 0) |
1210 | #define write_c0_count(val) __write_32bit_c0_register($9, 0, val) | 1356 | #define write_c0_count(val) __write_32bit_c0_register($9, 0, val) |
1211 | 1357 | ||
@@ -1218,9 +1364,21 @@ do { \ | |||
1218 | #define read_c0_entryhi() __read_ulong_c0_register($10, 0) | 1364 | #define read_c0_entryhi() __read_ulong_c0_register($10, 0) |
1219 | #define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) | 1365 | #define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) |
1220 | 1366 | ||
1367 | #define read_c0_guestctl1() __read_32bit_c0_register($10, 4) | ||
1368 | #define write_c0_guestctl1(val) __write_32bit_c0_register($10, 4, val) | ||
1369 | |||
1370 | #define read_c0_guestctl2() __read_32bit_c0_register($10, 5) | ||
1371 | #define write_c0_guestctl2(val) __write_32bit_c0_register($10, 5, val) | ||
1372 | |||
1373 | #define read_c0_guestctl3() __read_32bit_c0_register($10, 6) | ||
1374 | #define write_c0_guestctl3(val) __write_32bit_c0_register($10, 6, val) | ||
1375 | |||
1221 | #define read_c0_compare() __read_32bit_c0_register($11, 0) | 1376 | #define read_c0_compare() __read_32bit_c0_register($11, 0) |
1222 | #define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) | 1377 | #define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) |
1223 | 1378 | ||
1379 | #define read_c0_guestctl0ext() __read_32bit_c0_register($11, 4) | ||
1380 | #define write_c0_guestctl0ext(val) __write_32bit_c0_register($11, 4, val) | ||
1381 | |||
1224 | #define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */ | 1382 | #define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */ |
1225 | #define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val) | 1383 | #define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val) |
1226 | 1384 | ||
@@ -1231,6 +1389,12 @@ do { \ | |||
1231 | 1389 | ||
1232 | #define write_c0_status(val) __write_32bit_c0_register($12, 0, val) | 1390 | #define write_c0_status(val) __write_32bit_c0_register($12, 0, val) |
1233 | 1391 | ||
1392 | #define read_c0_guestctl0() __read_32bit_c0_register($12, 6) | ||
1393 | #define write_c0_guestctl0(val) __write_32bit_c0_register($12, 6, val) | ||
1394 | |||
1395 | #define read_c0_gtoffset() __read_32bit_c0_register($12, 7) | ||
1396 | #define write_c0_gtoffset(val) __write_32bit_c0_register($12, 7, val) | ||
1397 | |||
1234 | #define read_c0_cause() __read_32bit_c0_register($13, 0) | 1398 | #define read_c0_cause() __read_32bit_c0_register($13, 0) |
1235 | #define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) | 1399 | #define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) |
1236 | 1400 | ||
@@ -1416,6 +1580,9 @@ do { \ | |||
1416 | #define read_c0_ebase() __read_32bit_c0_register($15, 1) | 1580 | #define read_c0_ebase() __read_32bit_c0_register($15, 1) |
1417 | #define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val) | 1581 | #define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val) |
1418 | 1582 | ||
1583 | #define read_c0_ebase_64() __read_64bit_c0_register($15, 1) | ||
1584 | #define write_c0_ebase_64(val) __write_64bit_c0_register($15, 1, val) | ||
1585 | |||
1419 | #define read_c0_cdmmbase() __read_ulong_c0_register($15, 2) | 1586 | #define read_c0_cdmmbase() __read_ulong_c0_register($15, 2) |
1420 | #define write_c0_cdmmbase(val) __write_ulong_c0_register($15, 2, val) | 1587 | #define write_c0_cdmmbase(val) __write_ulong_c0_register($15, 2, val) |
1421 | 1588 | ||
@@ -1442,6 +1609,12 @@ do { \ | |||
1442 | #define read_c0_pwctl() __read_32bit_c0_register($6, 6) | 1609 | #define read_c0_pwctl() __read_32bit_c0_register($6, 6) |
1443 | #define write_c0_pwctl(val) __write_32bit_c0_register($6, 6, val) | 1610 | #define write_c0_pwctl(val) __write_32bit_c0_register($6, 6, val) |
1444 | 1611 | ||
1612 | #define read_c0_pgd() __read_64bit_c0_register($9, 7) | ||
1613 | #define write_c0_pgd(val) __write_64bit_c0_register($9, 7, val) | ||
1614 | |||
1615 | #define read_c0_kpgd() __read_64bit_c0_register($31, 7) | ||
1616 | #define write_c0_kpgd(val) __write_64bit_c0_register($31, 7, val) | ||
1617 | |||
1445 | /* Cavium OCTEON (cnMIPS) */ | 1618 | /* Cavium OCTEON (cnMIPS) */ |
1446 | #define read_c0_cvmcount() __read_ulong_c0_register($9, 6) | 1619 | #define read_c0_cvmcount() __read_ulong_c0_register($9, 6) |
1447 | #define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val) | 1620 | #define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val) |
@@ -1507,6 +1680,317 @@ do { \ | |||
1507 | #define write_c0_brcm_sleepcount(val) __write_32bit_c0_register($22, 7, val) | 1680 | #define write_c0_brcm_sleepcount(val) __write_32bit_c0_register($22, 7, val) |
1508 | 1681 | ||
1509 | /* | 1682 | /* |
1683 | * Macros to access the guest system control coprocessor | ||
1684 | */ | ||
1685 | |||
1686 | #ifdef TOOLCHAIN_SUPPORTS_VIRT | ||
1687 | |||
1688 | #define __read_32bit_gc0_register(source, sel) \ | ||
1689 | ({ int __res; \ | ||
1690 | __asm__ __volatile__( \ | ||
1691 | ".set\tpush\n\t" \ | ||
1692 | ".set\tmips32r2\n\t" \ | ||
1693 | ".set\tvirt\n\t" \ | ||
1694 | "mfgc0\t%0, $%1, %2\n\t" \ | ||
1695 | ".set\tpop" \ | ||
1696 | : "=r" (__res) \ | ||
1697 | : "i" (source), "i" (sel)); \ | ||
1698 | __res; \ | ||
1699 | }) | ||
1700 | |||
1701 | #define __read_64bit_gc0_register(source, sel) \ | ||
1702 | ({ unsigned long long __res; \ | ||
1703 | __asm__ __volatile__( \ | ||
1704 | ".set\tpush\n\t" \ | ||
1705 | ".set\tmips64r2\n\t" \ | ||
1706 | ".set\tvirt\n\t" \ | ||
1707 | "dmfgc0\t%0, $%1, %2\n\t" \ | ||
1708 | ".set\tpop" \ | ||
1709 | : "=r" (__res) \ | ||
1710 | : "i" (source), "i" (sel)); \ | ||
1711 | __res; \ | ||
1712 | }) | ||
1713 | |||
1714 | #define __write_32bit_gc0_register(register, sel, value) \ | ||
1715 | do { \ | ||
1716 | __asm__ __volatile__( \ | ||
1717 | ".set\tpush\n\t" \ | ||
1718 | ".set\tmips32r2\n\t" \ | ||
1719 | ".set\tvirt\n\t" \ | ||
1720 | "mtgc0\t%z0, $%1, %2\n\t" \ | ||
1721 | ".set\tpop" \ | ||
1722 | : : "Jr" ((unsigned int)(value)), \ | ||
1723 | "i" (register), "i" (sel)); \ | ||
1724 | } while (0) | ||
1725 | |||
1726 | #define __write_64bit_gc0_register(register, sel, value) \ | ||
1727 | do { \ | ||
1728 | __asm__ __volatile__( \ | ||
1729 | ".set\tpush\n\t" \ | ||
1730 | ".set\tmips64r2\n\t" \ | ||
1731 | ".set\tvirt\n\t" \ | ||
1732 | "dmtgc0\t%z0, $%1, %2\n\t" \ | ||
1733 | ".set\tpop" \ | ||
1734 | : : "Jr" (value), \ | ||
1735 | "i" (register), "i" (sel)); \ | ||
1736 | } while (0) | ||
1737 | |||
1738 | #else /* TOOLCHAIN_SUPPORTS_VIRT */ | ||
1739 | |||
1740 | #define __read_32bit_gc0_register(source, sel) \ | ||
1741 | ({ int __res; \ | ||
1742 | __asm__ __volatile__( \ | ||
1743 | ".set\tpush\n\t" \ | ||
1744 | ".set\tnoat\n\t" \ | ||
1745 | "# mfgc0\t$1, $%1, %2\n\t" \ | ||
1746 | ".word\t(0x40610000 | %1 << 11 | %2)\n\t" \ | ||
1747 | "move\t%0, $1\n\t" \ | ||
1748 | ".set\tpop" \ | ||
1749 | : "=r" (__res) \ | ||
1750 | : "i" (source), "i" (sel)); \ | ||
1751 | __res; \ | ||
1752 | }) | ||
1753 | |||
1754 | #define __read_64bit_gc0_register(source, sel) \ | ||
1755 | ({ unsigned long long __res; \ | ||
1756 | __asm__ __volatile__( \ | ||
1757 | ".set\tpush\n\t" \ | ||
1758 | ".set\tnoat\n\t" \ | ||
1759 | "# dmfgc0\t$1, $%1, %2\n\t" \ | ||
1760 | ".word\t(0x40610100 | %1 << 11 | %2)\n\t" \ | ||
1761 | "move\t%0, $1\n\t" \ | ||
1762 | ".set\tpop" \ | ||
1763 | : "=r" (__res) \ | ||
1764 | : "i" (source), "i" (sel)); \ | ||
1765 | __res; \ | ||
1766 | }) | ||
1767 | |||
1768 | #define __write_32bit_gc0_register(register, sel, value) \ | ||
1769 | do { \ | ||
1770 | __asm__ __volatile__( \ | ||
1771 | ".set\tpush\n\t" \ | ||
1772 | ".set\tnoat\n\t" \ | ||
1773 | "move\t$1, %0\n\t" \ | ||
1774 | "# mtgc0\t$1, $%1, %2\n\t" \ | ||
1775 | ".word\t(0x40610200 | %1 << 11 | %2)\n\t" \ | ||
1776 | ".set\tpop" \ | ||
1777 | : : "Jr" ((unsigned int)(value)), \ | ||
1778 | "i" (register), "i" (sel)); \ | ||
1779 | } while (0) | ||
1780 | |||
1781 | #define __write_64bit_gc0_register(register, sel, value) \ | ||
1782 | do { \ | ||
1783 | __asm__ __volatile__( \ | ||
1784 | ".set\tpush\n\t" \ | ||
1785 | ".set\tnoat\n\t" \ | ||
1786 | "move\t$1, %0\n\t" \ | ||
1787 | "# dmtgc0\t$1, $%1, %2\n\t" \ | ||
1788 | ".word\t(0x40610300 | %1 << 11 | %2)\n\t" \ | ||
1789 | ".set\tpop" \ | ||
1790 | : : "Jr" (value), \ | ||
1791 | "i" (register), "i" (sel)); \ | ||
1792 | } while (0) | ||
1793 | |||
1794 | #endif /* !TOOLCHAIN_SUPPORTS_VIRT */ | ||
1795 | |||
1796 | #define __read_ulong_gc0_register(reg, sel) \ | ||
1797 | ((sizeof(unsigned long) == 4) ? \ | ||
1798 | (unsigned long) __read_32bit_gc0_register(reg, sel) : \ | ||
1799 | (unsigned long) __read_64bit_gc0_register(reg, sel)) | ||
1800 | |||
1801 | #define __write_ulong_gc0_register(reg, sel, val) \ | ||
1802 | do { \ | ||
1803 | if (sizeof(unsigned long) == 4) \ | ||
1804 | __write_32bit_gc0_register(reg, sel, val); \ | ||
1805 | else \ | ||
1806 | __write_64bit_gc0_register(reg, sel, val); \ | ||
1807 | } while (0) | ||
1808 | |||
1809 | #define read_gc0_index() __read_32bit_gc0_register(0, 0) | ||
1810 | #define write_gc0_index(val) __write_32bit_gc0_register(0, 0, val) | ||
1811 | |||
1812 | #define read_gc0_entrylo0() __read_ulong_gc0_register(2, 0) | ||
1813 | #define write_gc0_entrylo0(val) __write_ulong_gc0_register(2, 0, val) | ||
1814 | |||
1815 | #define read_gc0_entrylo1() __read_ulong_gc0_register(3, 0) | ||
1816 | #define write_gc0_entrylo1(val) __write_ulong_gc0_register(3, 0, val) | ||
1817 | |||
1818 | #define read_gc0_context() __read_ulong_gc0_register(4, 0) | ||
1819 | #define write_gc0_context(val) __write_ulong_gc0_register(4, 0, val) | ||
1820 | |||
1821 | #define read_gc0_contextconfig() __read_32bit_gc0_register(4, 1) | ||
1822 | #define write_gc0_contextconfig(val) __write_32bit_gc0_register(4, 1, val) | ||
1823 | |||
1824 | #define read_gc0_userlocal() __read_ulong_gc0_register(4, 2) | ||
1825 | #define write_gc0_userlocal(val) __write_ulong_gc0_register(4, 2, val) | ||
1826 | |||
1827 | #define read_gc0_xcontextconfig() __read_ulong_gc0_register(4, 3) | ||
1828 | #define write_gc0_xcontextconfig(val) __write_ulong_gc0_register(4, 3, val) | ||
1829 | |||
1830 | #define read_gc0_pagemask() __read_32bit_gc0_register(5, 0) | ||
1831 | #define write_gc0_pagemask(val) __write_32bit_gc0_register(5, 0, val) | ||
1832 | |||
1833 | #define read_gc0_pagegrain() __read_32bit_gc0_register(5, 1) | ||
1834 | #define write_gc0_pagegrain(val) __write_32bit_gc0_register(5, 1, val) | ||
1835 | |||
1836 | #define read_gc0_segctl0() __read_ulong_gc0_register(5, 2) | ||
1837 | #define write_gc0_segctl0(val) __write_ulong_gc0_register(5, 2, val) | ||
1838 | |||
1839 | #define read_gc0_segctl1() __read_ulong_gc0_register(5, 3) | ||
1840 | #define write_gc0_segctl1(val) __write_ulong_gc0_register(5, 3, val) | ||
1841 | |||
1842 | #define read_gc0_segctl2() __read_ulong_gc0_register(5, 4) | ||
1843 | #define write_gc0_segctl2(val) __write_ulong_gc0_register(5, 4, val) | ||
1844 | |||
1845 | #define read_gc0_pwbase() __read_ulong_gc0_register(5, 5) | ||
1846 | #define write_gc0_pwbase(val) __write_ulong_gc0_register(5, 5, val) | ||
1847 | |||
1848 | #define read_gc0_pwfield() __read_ulong_gc0_register(5, 6) | ||
1849 | #define write_gc0_pwfield(val) __write_ulong_gc0_register(5, 6, val) | ||
1850 | |||
1851 | #define read_gc0_pwsize() __read_ulong_gc0_register(5, 7) | ||
1852 | #define write_gc0_pwsize(val) __write_ulong_gc0_register(5, 7, val) | ||
1853 | |||
1854 | #define read_gc0_wired() __read_32bit_gc0_register(6, 0) | ||
1855 | #define write_gc0_wired(val) __write_32bit_gc0_register(6, 0, val) | ||
1856 | |||
1857 | #define read_gc0_pwctl() __read_32bit_gc0_register(6, 6) | ||
1858 | #define write_gc0_pwctl(val) __write_32bit_gc0_register(6, 6, val) | ||
1859 | |||
1860 | #define read_gc0_hwrena() __read_32bit_gc0_register(7, 0) | ||
1861 | #define write_gc0_hwrena(val) __write_32bit_gc0_register(7, 0, val) | ||
1862 | |||
1863 | #define read_gc0_badvaddr() __read_ulong_gc0_register(8, 0) | ||
1864 | #define write_gc0_badvaddr(val) __write_ulong_gc0_register(8, 0, val) | ||
1865 | |||
1866 | #define read_gc0_badinstr() __read_32bit_gc0_register(8, 1) | ||
1867 | #define write_gc0_badinstr(val) __write_32bit_gc0_register(8, 1, val) | ||
1868 | |||
1869 | #define read_gc0_badinstrp() __read_32bit_gc0_register(8, 2) | ||
1870 | #define write_gc0_badinstrp(val) __write_32bit_gc0_register(8, 2, val) | ||
1871 | |||
1872 | #define read_gc0_count() __read_32bit_gc0_register(9, 0) | ||
1873 | |||
1874 | #define read_gc0_entryhi() __read_ulong_gc0_register(10, 0) | ||
1875 | #define write_gc0_entryhi(val) __write_ulong_gc0_register(10, 0, val) | ||
1876 | |||
1877 | #define read_gc0_compare() __read_32bit_gc0_register(11, 0) | ||
1878 | #define write_gc0_compare(val) __write_32bit_gc0_register(11, 0, val) | ||
1879 | |||
1880 | #define read_gc0_status() __read_32bit_gc0_register(12, 0) | ||
1881 | #define write_gc0_status(val) __write_32bit_gc0_register(12, 0, val) | ||
1882 | |||
1883 | #define read_gc0_intctl() __read_32bit_gc0_register(12, 1) | ||
1884 | #define write_gc0_intctl(val) __write_32bit_gc0_register(12, 1, val) | ||
1885 | |||
1886 | #define read_gc0_cause() __read_32bit_gc0_register(13, 0) | ||
1887 | #define write_gc0_cause(val) __write_32bit_gc0_register(13, 0, val) | ||
1888 | |||
1889 | #define read_gc0_epc() __read_ulong_gc0_register(14, 0) | ||
1890 | #define write_gc0_epc(val) __write_ulong_gc0_register(14, 0, val) | ||
1891 | |||
1892 | #define read_gc0_ebase() __read_32bit_gc0_register(15, 1) | ||
1893 | #define write_gc0_ebase(val) __write_32bit_gc0_register(15, 1, val) | ||
1894 | |||
1895 | #define read_gc0_ebase_64() __read_64bit_gc0_register(15, 1) | ||
1896 | #define write_gc0_ebase_64(val) __write_64bit_gc0_register(15, 1, val) | ||
1897 | |||
1898 | #define read_gc0_config() __read_32bit_gc0_register(16, 0) | ||
1899 | #define read_gc0_config1() __read_32bit_gc0_register(16, 1) | ||
1900 | #define read_gc0_config2() __read_32bit_gc0_register(16, 2) | ||
1901 | #define read_gc0_config3() __read_32bit_gc0_register(16, 3) | ||
1902 | #define read_gc0_config4() __read_32bit_gc0_register(16, 4) | ||
1903 | #define read_gc0_config5() __read_32bit_gc0_register(16, 5) | ||
1904 | #define read_gc0_config6() __read_32bit_gc0_register(16, 6) | ||
1905 | #define read_gc0_config7() __read_32bit_gc0_register(16, 7) | ||
1906 | #define write_gc0_config(val) __write_32bit_gc0_register(16, 0, val) | ||
1907 | #define write_gc0_config1(val) __write_32bit_gc0_register(16, 1, val) | ||
1908 | #define write_gc0_config2(val) __write_32bit_gc0_register(16, 2, val) | ||
1909 | #define write_gc0_config3(val) __write_32bit_gc0_register(16, 3, val) | ||
1910 | #define write_gc0_config4(val) __write_32bit_gc0_register(16, 4, val) | ||
1911 | #define write_gc0_config5(val) __write_32bit_gc0_register(16, 5, val) | ||
1912 | #define write_gc0_config6(val) __write_32bit_gc0_register(16, 6, val) | ||
1913 | #define write_gc0_config7(val) __write_32bit_gc0_register(16, 7, val) | ||
1914 | |||
1915 | #define read_gc0_watchlo0() __read_ulong_gc0_register(18, 0) | ||
1916 | #define read_gc0_watchlo1() __read_ulong_gc0_register(18, 1) | ||
1917 | #define read_gc0_watchlo2() __read_ulong_gc0_register(18, 2) | ||
1918 | #define read_gc0_watchlo3() __read_ulong_gc0_register(18, 3) | ||
1919 | #define read_gc0_watchlo4() __read_ulong_gc0_register(18, 4) | ||
1920 | #define read_gc0_watchlo5() __read_ulong_gc0_register(18, 5) | ||
1921 | #define read_gc0_watchlo6() __read_ulong_gc0_register(18, 6) | ||
1922 | #define read_gc0_watchlo7() __read_ulong_gc0_register(18, 7) | ||
1923 | #define write_gc0_watchlo0(val) __write_ulong_gc0_register(18, 0, val) | ||
1924 | #define write_gc0_watchlo1(val) __write_ulong_gc0_register(18, 1, val) | ||
1925 | #define write_gc0_watchlo2(val) __write_ulong_gc0_register(18, 2, val) | ||
1926 | #define write_gc0_watchlo3(val) __write_ulong_gc0_register(18, 3, val) | ||
1927 | #define write_gc0_watchlo4(val) __write_ulong_gc0_register(18, 4, val) | ||
1928 | #define write_gc0_watchlo5(val) __write_ulong_gc0_register(18, 5, val) | ||
1929 | #define write_gc0_watchlo6(val) __write_ulong_gc0_register(18, 6, val) | ||
1930 | #define write_gc0_watchlo7(val) __write_ulong_gc0_register(18, 7, val) | ||
1931 | |||
1932 | #define read_gc0_watchhi0() __read_32bit_gc0_register(19, 0) | ||
1933 | #define read_gc0_watchhi1() __read_32bit_gc0_register(19, 1) | ||
1934 | #define read_gc0_watchhi2() __read_32bit_gc0_register(19, 2) | ||
1935 | #define read_gc0_watchhi3() __read_32bit_gc0_register(19, 3) | ||
1936 | #define read_gc0_watchhi4() __read_32bit_gc0_register(19, 4) | ||
1937 | #define read_gc0_watchhi5() __read_32bit_gc0_register(19, 5) | ||
1938 | #define read_gc0_watchhi6() __read_32bit_gc0_register(19, 6) | ||
1939 | #define read_gc0_watchhi7() __read_32bit_gc0_register(19, 7) | ||
1940 | #define write_gc0_watchhi0(val) __write_32bit_gc0_register(19, 0, val) | ||
1941 | #define write_gc0_watchhi1(val) __write_32bit_gc0_register(19, 1, val) | ||
1942 | #define write_gc0_watchhi2(val) __write_32bit_gc0_register(19, 2, val) | ||
1943 | #define write_gc0_watchhi3(val) __write_32bit_gc0_register(19, 3, val) | ||
1944 | #define write_gc0_watchhi4(val) __write_32bit_gc0_register(19, 4, val) | ||
1945 | #define write_gc0_watchhi5(val) __write_32bit_gc0_register(19, 5, val) | ||
1946 | #define write_gc0_watchhi6(val) __write_32bit_gc0_register(19, 6, val) | ||
1947 | #define write_gc0_watchhi7(val) __write_32bit_gc0_register(19, 7, val) | ||
1948 | |||
1949 | #define read_gc0_xcontext() __read_ulong_gc0_register(20, 0) | ||
1950 | #define write_gc0_xcontext(val) __write_ulong_gc0_register(20, 0, val) | ||
1951 | |||
1952 | #define read_gc0_perfctrl0() __read_32bit_gc0_register(25, 0) | ||
1953 | #define write_gc0_perfctrl0(val) __write_32bit_gc0_register(25, 0, val) | ||
1954 | #define read_gc0_perfcntr0() __read_32bit_gc0_register(25, 1) | ||
1955 | #define write_gc0_perfcntr0(val) __write_32bit_gc0_register(25, 1, val) | ||
1956 | #define read_gc0_perfcntr0_64() __read_64bit_gc0_register(25, 1) | ||
1957 | #define write_gc0_perfcntr0_64(val) __write_64bit_gc0_register(25, 1, val) | ||
1958 | #define read_gc0_perfctrl1() __read_32bit_gc0_register(25, 2) | ||
1959 | #define write_gc0_perfctrl1(val) __write_32bit_gc0_register(25, 2, val) | ||
1960 | #define read_gc0_perfcntr1() __read_32bit_gc0_register(25, 3) | ||
1961 | #define write_gc0_perfcntr1(val) __write_32bit_gc0_register(25, 3, val) | ||
1962 | #define read_gc0_perfcntr1_64() __read_64bit_gc0_register(25, 3) | ||
1963 | #define write_gc0_perfcntr1_64(val) __write_64bit_gc0_register(25, 3, val) | ||
1964 | #define read_gc0_perfctrl2() __read_32bit_gc0_register(25, 4) | ||
1965 | #define write_gc0_perfctrl2(val) __write_32bit_gc0_register(25, 4, val) | ||
1966 | #define read_gc0_perfcntr2() __read_32bit_gc0_register(25, 5) | ||
1967 | #define write_gc0_perfcntr2(val) __write_32bit_gc0_register(25, 5, val) | ||
1968 | #define read_gc0_perfcntr2_64() __read_64bit_gc0_register(25, 5) | ||
1969 | #define write_gc0_perfcntr2_64(val) __write_64bit_gc0_register(25, 5, val) | ||
1970 | #define read_gc0_perfctrl3() __read_32bit_gc0_register(25, 6) | ||
1971 | #define write_gc0_perfctrl3(val) __write_32bit_gc0_register(25, 6, val) | ||
1972 | #define read_gc0_perfcntr3() __read_32bit_gc0_register(25, 7) | ||
1973 | #define write_gc0_perfcntr3(val) __write_32bit_gc0_register(25, 7, val) | ||
1974 | #define read_gc0_perfcntr3_64() __read_64bit_gc0_register(25, 7) | ||
1975 | #define write_gc0_perfcntr3_64(val) __write_64bit_gc0_register(25, 7, val) | ||
1976 | |||
1977 | #define read_gc0_errorepc() __read_ulong_gc0_register(30, 0) | ||
1978 | #define write_gc0_errorepc(val) __write_ulong_gc0_register(30, 0, val) | ||
1979 | |||
1980 | #define read_gc0_kscratch1() __read_ulong_gc0_register(31, 2) | ||
1981 | #define read_gc0_kscratch2() __read_ulong_gc0_register(31, 3) | ||
1982 | #define read_gc0_kscratch3() __read_ulong_gc0_register(31, 4) | ||
1983 | #define read_gc0_kscratch4() __read_ulong_gc0_register(31, 5) | ||
1984 | #define read_gc0_kscratch5() __read_ulong_gc0_register(31, 6) | ||
1985 | #define read_gc0_kscratch6() __read_ulong_gc0_register(31, 7) | ||
1986 | #define write_gc0_kscratch1(val) __write_ulong_gc0_register(31, 2, val) | ||
1987 | #define write_gc0_kscratch2(val) __write_ulong_gc0_register(31, 3, val) | ||
1988 | #define write_gc0_kscratch3(val) __write_ulong_gc0_register(31, 4, val) | ||
1989 | #define write_gc0_kscratch4(val) __write_ulong_gc0_register(31, 5, val) | ||
1990 | #define write_gc0_kscratch5(val) __write_ulong_gc0_register(31, 6, val) | ||
1991 | #define write_gc0_kscratch6(val) __write_ulong_gc0_register(31, 7, val) | ||
1992 | |||
1993 | /* | ||
1510 | * Macros to access the floating point coprocessor control registers | 1994 | * Macros to access the floating point coprocessor control registers |
1511 | */ | 1995 | */ |
1512 | #define _read_32bit_cp1_register(source, gas_hardfloat) \ | 1996 | #define _read_32bit_cp1_register(source, gas_hardfloat) \ |
@@ -2001,47 +2485,159 @@ static inline void tlb_write_random(void) | |||
2001 | ".set reorder"); | 2485 | ".set reorder"); |
2002 | } | 2486 | } |
2003 | 2487 | ||
2488 | #ifdef TOOLCHAIN_SUPPORTS_VIRT | ||
2489 | |||
2004 | /* | 2490 | /* |
2005 | * Manipulate bits in a c0 register. | 2491 | * Guest TLB operations. |
2492 | * | ||
2493 | * It is responsibility of the caller to take care of any TLB hazards. | ||
2006 | */ | 2494 | */ |
2007 | #define __BUILD_SET_C0(name) \ | 2495 | static inline void guest_tlb_probe(void) |
2496 | { | ||
2497 | __asm__ __volatile__( | ||
2498 | ".set push\n\t" | ||
2499 | ".set noreorder\n\t" | ||
2500 | ".set virt\n\t" | ||
2501 | "tlbgp\n\t" | ||
2502 | ".set pop"); | ||
2503 | } | ||
2504 | |||
2505 | static inline void guest_tlb_read(void) | ||
2506 | { | ||
2507 | __asm__ __volatile__( | ||
2508 | ".set push\n\t" | ||
2509 | ".set noreorder\n\t" | ||
2510 | ".set virt\n\t" | ||
2511 | "tlbgr\n\t" | ||
2512 | ".set pop"); | ||
2513 | } | ||
2514 | |||
2515 | static inline void guest_tlb_write_indexed(void) | ||
2516 | { | ||
2517 | __asm__ __volatile__( | ||
2518 | ".set push\n\t" | ||
2519 | ".set noreorder\n\t" | ||
2520 | ".set virt\n\t" | ||
2521 | "tlbgwi\n\t" | ||
2522 | ".set pop"); | ||
2523 | } | ||
2524 | |||
2525 | static inline void guest_tlb_write_random(void) | ||
2526 | { | ||
2527 | __asm__ __volatile__( | ||
2528 | ".set push\n\t" | ||
2529 | ".set noreorder\n\t" | ||
2530 | ".set virt\n\t" | ||
2531 | "tlbgwr\n\t" | ||
2532 | ".set pop"); | ||
2533 | } | ||
2534 | |||
2535 | /* | ||
2536 | * Guest TLB Invalidate Flush | ||
2537 | */ | ||
2538 | static inline void guest_tlbinvf(void) | ||
2539 | { | ||
2540 | __asm__ __volatile__( | ||
2541 | ".set push\n\t" | ||
2542 | ".set noreorder\n\t" | ||
2543 | ".set virt\n\t" | ||
2544 | "tlbginvf\n\t" | ||
2545 | ".set pop"); | ||
2546 | } | ||
2547 | |||
2548 | #else /* TOOLCHAIN_SUPPORTS_VIRT */ | ||
2549 | |||
2550 | /* | ||
2551 | * Guest TLB operations. | ||
2552 | * | ||
2553 | * It is responsibility of the caller to take care of any TLB hazards. | ||
2554 | */ | ||
2555 | static inline void guest_tlb_probe(void) | ||
2556 | { | ||
2557 | __asm__ __volatile__( | ||
2558 | "# tlbgp\n\t" | ||
2559 | ".word 0x42000010"); | ||
2560 | } | ||
2561 | |||
2562 | static inline void guest_tlb_read(void) | ||
2563 | { | ||
2564 | __asm__ __volatile__( | ||
2565 | "# tlbgr\n\t" | ||
2566 | ".word 0x42000009"); | ||
2567 | } | ||
2568 | |||
2569 | static inline void guest_tlb_write_indexed(void) | ||
2570 | { | ||
2571 | __asm__ __volatile__( | ||
2572 | "# tlbgwi\n\t" | ||
2573 | ".word 0x4200000a"); | ||
2574 | } | ||
2575 | |||
2576 | static inline void guest_tlb_write_random(void) | ||
2577 | { | ||
2578 | __asm__ __volatile__( | ||
2579 | "# tlbgwr\n\t" | ||
2580 | ".word 0x4200000e"); | ||
2581 | } | ||
2582 | |||
2583 | /* | ||
2584 | * Guest TLB Invalidate Flush | ||
2585 | */ | ||
2586 | static inline void guest_tlbinvf(void) | ||
2587 | { | ||
2588 | __asm__ __volatile__( | ||
2589 | "# tlbginvf\n\t" | ||
2590 | ".word 0x4200000c"); | ||
2591 | } | ||
2592 | |||
2593 | #endif /* !TOOLCHAIN_SUPPORTS_VIRT */ | ||
2594 | |||
2595 | /* | ||
2596 | * Manipulate bits in a register. | ||
2597 | */ | ||
2598 | #define __BUILD_SET_COMMON(name) \ | ||
2008 | static inline unsigned int \ | 2599 | static inline unsigned int \ |
2009 | set_c0_##name(unsigned int set) \ | 2600 | set_##name(unsigned int set) \ |
2010 | { \ | 2601 | { \ |
2011 | unsigned int res, new; \ | 2602 | unsigned int res, new; \ |
2012 | \ | 2603 | \ |
2013 | res = read_c0_##name(); \ | 2604 | res = read_##name(); \ |
2014 | new = res | set; \ | 2605 | new = res | set; \ |
2015 | write_c0_##name(new); \ | 2606 | write_##name(new); \ |
2016 | \ | 2607 | \ |
2017 | return res; \ | 2608 | return res; \ |
2018 | } \ | 2609 | } \ |
2019 | \ | 2610 | \ |
2020 | static inline unsigned int \ | 2611 | static inline unsigned int \ |
2021 | clear_c0_##name(unsigned int clear) \ | 2612 | clear_##name(unsigned int clear) \ |
2022 | { \ | 2613 | { \ |
2023 | unsigned int res, new; \ | 2614 | unsigned int res, new; \ |
2024 | \ | 2615 | \ |
2025 | res = read_c0_##name(); \ | 2616 | res = read_##name(); \ |
2026 | new = res & ~clear; \ | 2617 | new = res & ~clear; \ |
2027 | write_c0_##name(new); \ | 2618 | write_##name(new); \ |
2028 | \ | 2619 | \ |
2029 | return res; \ | 2620 | return res; \ |
2030 | } \ | 2621 | } \ |
2031 | \ | 2622 | \ |
2032 | static inline unsigned int \ | 2623 | static inline unsigned int \ |
2033 | change_c0_##name(unsigned int change, unsigned int val) \ | 2624 | change_##name(unsigned int change, unsigned int val) \ |
2034 | { \ | 2625 | { \ |
2035 | unsigned int res, new; \ | 2626 | unsigned int res, new; \ |
2036 | \ | 2627 | \ |
2037 | res = read_c0_##name(); \ | 2628 | res = read_##name(); \ |
2038 | new = res & ~change; \ | 2629 | new = res & ~change; \ |
2039 | new |= (val & change); \ | 2630 | new |= (val & change); \ |
2040 | write_c0_##name(new); \ | 2631 | write_##name(new); \ |
2041 | \ | 2632 | \ |
2042 | return res; \ | 2633 | return res; \ |
2043 | } | 2634 | } |
2044 | 2635 | ||
2636 | /* | ||
2637 | * Manipulate bits in a c0 register. | ||
2638 | */ | ||
2639 | #define __BUILD_SET_C0(name) __BUILD_SET_COMMON(c0_##name) | ||
2640 | |||
2045 | __BUILD_SET_C0(status) | 2641 | __BUILD_SET_C0(status) |
2046 | __BUILD_SET_C0(cause) | 2642 | __BUILD_SET_C0(cause) |
2047 | __BUILD_SET_C0(config) | 2643 | __BUILD_SET_C0(config) |
@@ -2050,6 +2646,11 @@ __BUILD_SET_C0(intcontrol) | |||
2050 | __BUILD_SET_C0(intctl) | 2646 | __BUILD_SET_C0(intctl) |
2051 | __BUILD_SET_C0(srsmap) | 2647 | __BUILD_SET_C0(srsmap) |
2052 | __BUILD_SET_C0(pagegrain) | 2648 | __BUILD_SET_C0(pagegrain) |
2649 | __BUILD_SET_C0(guestctl0) | ||
2650 | __BUILD_SET_C0(guestctl0ext) | ||
2651 | __BUILD_SET_C0(guestctl1) | ||
2652 | __BUILD_SET_C0(guestctl2) | ||
2653 | __BUILD_SET_C0(guestctl3) | ||
2053 | __BUILD_SET_C0(brcm_config_0) | 2654 | __BUILD_SET_C0(brcm_config_0) |
2054 | __BUILD_SET_C0(brcm_bus_pll) | 2655 | __BUILD_SET_C0(brcm_bus_pll) |
2055 | __BUILD_SET_C0(brcm_reset) | 2656 | __BUILD_SET_C0(brcm_reset) |
@@ -2059,12 +2660,21 @@ __BUILD_SET_C0(brcm_config) | |||
2059 | __BUILD_SET_C0(brcm_mode) | 2660 | __BUILD_SET_C0(brcm_mode) |
2060 | 2661 | ||
2061 | /* | 2662 | /* |
2663 | * Manipulate bits in a guest c0 register. | ||
2664 | */ | ||
2665 | #define __BUILD_SET_GC0(name) __BUILD_SET_COMMON(gc0_##name) | ||
2666 | |||
2667 | __BUILD_SET_GC0(status) | ||
2668 | __BUILD_SET_GC0(cause) | ||
2669 | __BUILD_SET_GC0(ebase) | ||
2670 | |||
2671 | /* | ||
2062 | * Return low 10 bits of ebase. | 2672 | * Return low 10 bits of ebase. |
2063 | * Note that under KVM (MIPSVZ) this returns vcpu id. | 2673 | * Note that under KVM (MIPSVZ) this returns vcpu id. |
2064 | */ | 2674 | */ |
2065 | static inline unsigned int get_ebase_cpunum(void) | 2675 | static inline unsigned int get_ebase_cpunum(void) |
2066 | { | 2676 | { |
2067 | return read_c0_ebase() & 0x3ff; | 2677 | return read_c0_ebase() & MIPS_EBASE_CPUNUM; |
2068 | } | 2678 | } |
2069 | 2679 | ||
2070 | #endif /* !__ASSEMBLY__ */ | 2680 | #endif /* !__ASSEMBLY__ */ |
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 45914b59824c..fc57e135cb0a 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h | |||
@@ -65,37 +65,32 @@ extern unsigned long pgd_current[]; | |||
65 | back_to_back_c0_hazard(); \ | 65 | back_to_back_c0_hazard(); \ |
66 | TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) | 66 | TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) |
67 | #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ | 67 | #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ |
68 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
69 | 68 | ||
70 | #define ASID_INC 0x40 | 69 | /* |
71 | #define ASID_MASK 0xfc0 | 70 | * All unused by hardware upper bits will be considered |
72 | 71 | * as a software asid extension. | |
73 | #elif defined(CONFIG_CPU_R8000) | 72 | */ |
74 | 73 | static unsigned long asid_version_mask(unsigned int cpu) | |
75 | #define ASID_INC 0x10 | 74 | { |
76 | #define ASID_MASK 0xff0 | 75 | unsigned long asid_mask = cpu_asid_mask(&cpu_data[cpu]); |
77 | |||
78 | #else /* FIXME: not correct for R6000 */ | ||
79 | 76 | ||
80 | #define ASID_INC 0x1 | 77 | return ~(asid_mask | (asid_mask - 1)); |
81 | #define ASID_MASK 0xff | 78 | } |
82 | 79 | ||
83 | #endif | 80 | static unsigned long asid_first_version(unsigned int cpu) |
81 | { | ||
82 | return ~asid_version_mask(cpu) + 1; | ||
83 | } | ||
84 | 84 | ||
85 | #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) | 85 | #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) |
86 | #define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) | ||
87 | #define asid_cache(cpu) (cpu_data[cpu].asid_cache) | 86 | #define asid_cache(cpu) (cpu_data[cpu].asid_cache) |
87 | #define cpu_asid(cpu, mm) \ | ||
88 | (cpu_context((cpu), (mm)) & cpu_asid_mask(&cpu_data[cpu])) | ||
88 | 89 | ||
89 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | 90 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) |
90 | { | 91 | { |
91 | } | 92 | } |
92 | 93 | ||
93 | /* | ||
94 | * All unused by hardware upper bits will be considered | ||
95 | * as a software asid extension. | ||
96 | */ | ||
97 | #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) | ||
98 | #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) | ||
99 | 94 | ||
100 | /* Normal, classic MIPS get_new_mmu_context */ | 95 | /* Normal, classic MIPS get_new_mmu_context */ |
101 | static inline void | 96 | static inline void |
@@ -104,7 +99,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
104 | extern void kvm_local_flush_tlb_all(void); | 99 | extern void kvm_local_flush_tlb_all(void); |
105 | unsigned long asid = asid_cache(cpu); | 100 | unsigned long asid = asid_cache(cpu); |
106 | 101 | ||
107 | if (! ((asid += ASID_INC) & ASID_MASK) ) { | 102 | if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) { |
108 | if (cpu_has_vtag_icache) | 103 | if (cpu_has_vtag_icache) |
109 | flush_icache_all(); | 104 | flush_icache_all(); |
110 | #ifdef CONFIG_KVM | 105 | #ifdef CONFIG_KVM |
@@ -113,7 +108,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
113 | local_flush_tlb_all(); /* start new asid cycle */ | 108 | local_flush_tlb_all(); /* start new asid cycle */ |
114 | #endif | 109 | #endif |
115 | if (!asid) /* fix version if needed */ | 110 | if (!asid) /* fix version if needed */ |
116 | asid = ASID_FIRST_VERSION; | 111 | asid = asid_first_version(cpu); |
117 | } | 112 | } |
118 | 113 | ||
119 | cpu_context(cpu, mm) = asid_cache(cpu) = asid; | 114 | cpu_context(cpu, mm) = asid_cache(cpu) = asid; |
@@ -145,7 +140,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
145 | 140 | ||
146 | htw_stop(); | 141 | htw_stop(); |
147 | /* Check if our ASID is of an older version and thus invalid */ | 142 | /* Check if our ASID is of an older version and thus invalid */ |
148 | if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) | 143 | if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & asid_version_mask(cpu)) |
149 | get_new_mmu_context(next, cpu); | 144 | get_new_mmu_context(next, cpu); |
150 | write_c0_entryhi(cpu_asid(cpu, next)); | 145 | write_c0_entryhi(cpu_asid(cpu, next)); |
151 | TLBMISS_HANDLER_SETUP_PGD(next->pgd); | 146 | TLBMISS_HANDLER_SETUP_PGD(next->pgd); |
diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h index bbb85fe21642..6e4effa6f626 100644 --- a/arch/mips/include/asm/msa.h +++ b/arch/mips/include/asm/msa.h | |||
@@ -147,6 +147,19 @@ static inline void restore_msa(struct task_struct *t) | |||
147 | _restore_msa(t); | 147 | _restore_msa(t); |
148 | } | 148 | } |
149 | 149 | ||
150 | static inline void init_msa_upper(void) | ||
151 | { | ||
152 | /* | ||
153 | * Check cpu_has_msa only if it's a constant. This will allow the | ||
154 | * compiler to optimise out code for CPUs without MSA without adding | ||
155 | * an extra redundant check for CPUs with MSA. | ||
156 | */ | ||
157 | if (__builtin_constant_p(cpu_has_msa) && !cpu_has_msa) | ||
158 | return; | ||
159 | |||
160 | _init_msa_upper(); | ||
161 | } | ||
162 | |||
150 | #ifdef TOOLCHAIN_SUPPORTS_MSA | 163 | #ifdef TOOLCHAIN_SUPPORTS_MSA |
151 | 164 | ||
152 | #define __BUILD_MSA_CTL_REG(name, cs) \ | 165 | #define __BUILD_MSA_CTL_REG(name, cs) \ |
diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h index d92cf59bdae6..62787765575e 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h +++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h | |||
@@ -32,6 +32,8 @@ | |||
32 | #ifndef __CVMX_BOOTINFO_H__ | 32 | #ifndef __CVMX_BOOTINFO_H__ |
33 | #define __CVMX_BOOTINFO_H__ | 33 | #define __CVMX_BOOTINFO_H__ |
34 | 34 | ||
35 | #include "cvmx-coremask.h" | ||
36 | |||
35 | /* | 37 | /* |
36 | * Current major and minor versions of the CVMX bootinfo block that is | 38 | * Current major and minor versions of the CVMX bootinfo block that is |
37 | * passed from the bootloader to the application. This is versioned | 39 | * passed from the bootloader to the application. This is versioned |
@@ -39,7 +41,7 @@ | |||
39 | * versions. | 41 | * versions. |
40 | */ | 42 | */ |
41 | #define CVMX_BOOTINFO_MAJ_VER 1 | 43 | #define CVMX_BOOTINFO_MAJ_VER 1 |
42 | #define CVMX_BOOTINFO_MIN_VER 3 | 44 | #define CVMX_BOOTINFO_MIN_VER 4 |
43 | 45 | ||
44 | #if (CVMX_BOOTINFO_MAJ_VER == 1) | 46 | #if (CVMX_BOOTINFO_MAJ_VER == 1) |
45 | #define CVMX_BOOTINFO_OCTEON_SERIAL_LEN 20 | 47 | #define CVMX_BOOTINFO_OCTEON_SERIAL_LEN 20 |
@@ -124,6 +126,13 @@ struct cvmx_bootinfo { | |||
124 | */ | 126 | */ |
125 | uint64_t fdt_addr; | 127 | uint64_t fdt_addr; |
126 | #endif | 128 | #endif |
129 | #if (CVMX_BOOTINFO_MIN_VER >= 4) | ||
130 | /* | ||
131 | * Coremask used for processors with more than 32 cores | ||
132 | * or with OCI. This replaces core_mask. | ||
133 | */ | ||
134 | struct cvmx_coremask ext_core_mask; | ||
135 | #endif | ||
127 | #else /* __BIG_ENDIAN */ | 136 | #else /* __BIG_ENDIAN */ |
128 | /* | 137 | /* |
129 | * Little-Endian: When the CPU mode is switched to | 138 | * Little-Endian: When the CPU mode is switched to |
@@ -177,6 +186,9 @@ struct cvmx_bootinfo { | |||
177 | #if (CVMX_BOOTINFO_MIN_VER >= 3) | 186 | #if (CVMX_BOOTINFO_MIN_VER >= 3) |
178 | uint64_t fdt_addr; | 187 | uint64_t fdt_addr; |
179 | #endif | 188 | #endif |
189 | #if (CVMX_BOOTINFO_MIN_VER >= 4) | ||
190 | struct cvmx_coremask ext_core_mask; | ||
191 | #endif | ||
180 | #endif | 192 | #endif |
181 | }; | 193 | }; |
182 | 194 | ||
@@ -388,7 +400,7 @@ static inline const char *cvmx_board_type_to_string(enum | |||
388 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901) | 400 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901) |
389 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX) | 401 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX) |
390 | } | 402 | } |
391 | return "Unsupported Board"; | 403 | return NULL; |
392 | } | 404 | } |
393 | 405 | ||
394 | #define ENUM_CHIP_TYPE_CASE(x) \ | 406 | #define ENUM_CHIP_TYPE_CASE(x) \ |
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu3-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu3-defs.h new file mode 100644 index 000000000000..547f778f5b05 --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-ciu3-defs.h | |||
@@ -0,0 +1,353 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2003-2016 Cavium Inc. | ||
3 | * | ||
4 | * This file is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License, Version 2, as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This file is distributed in the hope that it will be useful, but | ||
9 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | ||
11 | * NONINFRINGEMENT. See the GNU General Public License for more | ||
12 | * details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __CVMX_CIU3_DEFS_H__ | ||
17 | #define __CVMX_CIU3_DEFS_H__ | ||
18 | |||
19 | #define CVMX_CIU3_FUSE CVMX_ADD_IO_SEG(0x00010100000001A0ull) | ||
20 | #define CVMX_CIU3_BIST CVMX_ADD_IO_SEG(0x00010100000001C0ull) | ||
21 | #define CVMX_CIU3_CONST CVMX_ADD_IO_SEG(0x0001010000000220ull) | ||
22 | #define CVMX_CIU3_CTL CVMX_ADD_IO_SEG(0x00010100000000E0ull) | ||
23 | #define CVMX_CIU3_DESTX_IO_INT(offset) (CVMX_ADD_IO_SEG(0x0001010000210000ull) + ((offset) & 7) * 8) | ||
24 | #define CVMX_CIU3_DESTX_PP_INT(offset) (CVMX_ADD_IO_SEG(0x0001010000200000ull) + ((offset) & 255) * 8) | ||
25 | #define CVMX_CIU3_GSTOP CVMX_ADD_IO_SEG(0x0001010000000140ull) | ||
26 | #define CVMX_CIU3_IDTX_CTL(offset) (CVMX_ADD_IO_SEG(0x0001010000110000ull) + ((offset) & 255) * 8) | ||
27 | #define CVMX_CIU3_IDTX_IO(offset) (CVMX_ADD_IO_SEG(0x0001010000130000ull) + ((offset) & 255) * 8) | ||
28 | #define CVMX_CIU3_IDTX_PPX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001010000120000ull) + ((block_id) & 255) * 0x20ull) | ||
29 | #define CVMX_CIU3_INTR_RAM_ECC_CTL CVMX_ADD_IO_SEG(0x0001010000000260ull) | ||
30 | #define CVMX_CIU3_INTR_RAM_ECC_ST CVMX_ADD_IO_SEG(0x0001010000000280ull) | ||
31 | #define CVMX_CIU3_INTR_READY CVMX_ADD_IO_SEG(0x00010100000002A0ull) | ||
32 | #define CVMX_CIU3_INTR_SLOWDOWN CVMX_ADD_IO_SEG(0x0001010000000240ull) | ||
33 | #define CVMX_CIU3_ISCX_CTL(offset) (CVMX_ADD_IO_SEG(0x0001010080000000ull) + ((offset) & 1048575) * 8) | ||
34 | #define CVMX_CIU3_ISCX_W1C(offset) (CVMX_ADD_IO_SEG(0x0001010090000000ull) + ((offset) & 1048575) * 8) | ||
35 | #define CVMX_CIU3_ISCX_W1S(offset) (CVMX_ADD_IO_SEG(0x00010100A0000000ull) + ((offset) & 1048575) * 8) | ||
36 | #define CVMX_CIU3_NMI CVMX_ADD_IO_SEG(0x0001010000000160ull) | ||
37 | #define CVMX_CIU3_SISCX(offset) (CVMX_ADD_IO_SEG(0x0001010000220000ull) + ((offset) & 255) * 8) | ||
38 | #define CVMX_CIU3_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001010000010000ull) + ((offset) & 15) * 8) | ||
39 | |||
40 | union cvmx_ciu3_bist { | ||
41 | uint64_t u64; | ||
42 | struct cvmx_ciu3_bist_s { | ||
43 | #ifdef __BIG_ENDIAN_BITFIELD | ||
44 | uint64_t reserved_9_63 : 55; | ||
45 | uint64_t bist : 9; | ||
46 | #else | ||
47 | uint64_t bist : 9; | ||
48 | uint64_t reserved_9_63 : 55; | ||
49 | #endif | ||
50 | } s; | ||
51 | }; | ||
52 | |||
53 | union cvmx_ciu3_const { | ||
54 | uint64_t u64; | ||
55 | struct cvmx_ciu3_const_s { | ||
56 | #ifdef __BIG_ENDIAN_BITFIELD | ||
57 | uint64_t dests_io : 16; | ||
58 | uint64_t pintsn : 16; | ||
59 | uint64_t dests_pp : 16; | ||
60 | uint64_t idt : 16; | ||
61 | #else | ||
62 | uint64_t idt : 16; | ||
63 | uint64_t dests_pp : 16; | ||
64 | uint64_t pintsn : 16; | ||
65 | uint64_t dests_io : 16; | ||
66 | #endif | ||
67 | } s; | ||
68 | }; | ||
69 | |||
70 | union cvmx_ciu3_ctl { | ||
71 | uint64_t u64; | ||
72 | struct cvmx_ciu3_ctl_s { | ||
73 | #ifdef __BIG_ENDIAN_BITFIELD | ||
74 | uint64_t reserved_5_63 : 59; | ||
75 | uint64_t mcd_sel : 2; | ||
76 | uint64_t iscmem_le : 1; | ||
77 | uint64_t seq_dis : 1; | ||
78 | uint64_t cclk_dis : 1; | ||
79 | #else | ||
80 | uint64_t cclk_dis : 1; | ||
81 | uint64_t seq_dis : 1; | ||
82 | uint64_t iscmem_le : 1; | ||
83 | uint64_t mcd_sel : 2; | ||
84 | uint64_t reserved_5_63 : 59; | ||
85 | #endif | ||
86 | } s; | ||
87 | }; | ||
88 | |||
89 | union cvmx_ciu3_destx_io_int { | ||
90 | uint64_t u64; | ||
91 | struct cvmx_ciu3_destx_io_int_s { | ||
92 | #ifdef __BIG_ENDIAN_BITFIELD | ||
93 | uint64_t reserved_52_63 : 12; | ||
94 | uint64_t intsn : 20; | ||
95 | uint64_t reserved_10_31 : 22; | ||
96 | uint64_t intidt : 8; | ||
97 | uint64_t newint : 1; | ||
98 | uint64_t intr : 1; | ||
99 | #else | ||
100 | uint64_t intr : 1; | ||
101 | uint64_t newint : 1; | ||
102 | uint64_t intidt : 8; | ||
103 | uint64_t reserved_10_31 : 22; | ||
104 | uint64_t intsn : 20; | ||
105 | uint64_t reserved_52_63 : 12; | ||
106 | #endif | ||
107 | } s; | ||
108 | }; | ||
109 | |||
110 | union cvmx_ciu3_destx_pp_int { | ||
111 | uint64_t u64; | ||
112 | struct cvmx_ciu3_destx_pp_int_s { | ||
113 | #ifdef __BIG_ENDIAN_BITFIELD | ||
114 | uint64_t reserved_52_63 : 12; | ||
115 | uint64_t intsn : 20; | ||
116 | uint64_t reserved_10_31 : 22; | ||
117 | uint64_t intidt : 8; | ||
118 | uint64_t newint : 1; | ||
119 | uint64_t intr : 1; | ||
120 | #else | ||
121 | uint64_t intr : 1; | ||
122 | uint64_t newint : 1; | ||
123 | uint64_t intidt : 8; | ||
124 | uint64_t reserved_10_31 : 22; | ||
125 | uint64_t intsn : 20; | ||
126 | uint64_t reserved_52_63 : 12; | ||
127 | #endif | ||
128 | } s; | ||
129 | }; | ||
130 | |||
131 | union cvmx_ciu3_gstop { | ||
132 | uint64_t u64; | ||
133 | struct cvmx_ciu3_gstop_s { | ||
134 | #ifdef __BIG_ENDIAN_BITFIELD | ||
135 | uint64_t reserved_1_63 : 63; | ||
136 | uint64_t gstop : 1; | ||
137 | #else | ||
138 | uint64_t gstop : 1; | ||
139 | uint64_t reserved_1_63 : 63; | ||
140 | #endif | ||
141 | } s; | ||
142 | }; | ||
143 | |||
144 | union cvmx_ciu3_idtx_ctl { | ||
145 | uint64_t u64; | ||
146 | struct cvmx_ciu3_idtx_ctl_s { | ||
147 | #ifdef __BIG_ENDIAN_BITFIELD | ||
148 | uint64_t reserved_52_63 : 12; | ||
149 | uint64_t intsn : 20; | ||
150 | uint64_t reserved_4_31 : 28; | ||
151 | uint64_t intr : 1; | ||
152 | uint64_t newint : 1; | ||
153 | uint64_t ip_num : 2; | ||
154 | #else | ||
155 | uint64_t ip_num : 2; | ||
156 | uint64_t newint : 1; | ||
157 | uint64_t intr : 1; | ||
158 | uint64_t reserved_4_31 : 28; | ||
159 | uint64_t intsn : 20; | ||
160 | uint64_t reserved_52_63 : 12; | ||
161 | #endif | ||
162 | } s; | ||
163 | }; | ||
164 | |||
165 | union cvmx_ciu3_idtx_io { | ||
166 | uint64_t u64; | ||
167 | struct cvmx_ciu3_idtx_io_s { | ||
168 | #ifdef __BIG_ENDIAN_BITFIELD | ||
169 | uint64_t reserved_5_63 : 59; | ||
170 | uint64_t io : 5; | ||
171 | #else | ||
172 | uint64_t io : 5; | ||
173 | uint64_t reserved_5_63 : 59; | ||
174 | #endif | ||
175 | } s; | ||
176 | }; | ||
177 | |||
178 | union cvmx_ciu3_idtx_ppx { | ||
179 | uint64_t u64; | ||
180 | struct cvmx_ciu3_idtx_ppx_s { | ||
181 | #ifdef __BIG_ENDIAN_BITFIELD | ||
182 | uint64_t reserved_48_63 : 16; | ||
183 | uint64_t pp : 48; | ||
184 | #else | ||
185 | uint64_t pp : 48; | ||
186 | uint64_t reserved_48_63 : 16; | ||
187 | #endif | ||
188 | } s; | ||
189 | }; | ||
190 | |||
191 | union cvmx_ciu3_intr_ram_ecc_ctl { | ||
192 | uint64_t u64; | ||
193 | struct cvmx_ciu3_intr_ram_ecc_ctl_s { | ||
194 | #ifdef __BIG_ENDIAN_BITFIELD | ||
195 | uint64_t reserved_3_63 : 61; | ||
196 | uint64_t flip_synd : 2; | ||
197 | uint64_t ecc_ena : 1; | ||
198 | #else | ||
199 | uint64_t ecc_ena : 1; | ||
200 | uint64_t flip_synd : 2; | ||
201 | uint64_t reserved_3_63 : 61; | ||
202 | #endif | ||
203 | } s; | ||
204 | }; | ||
205 | |||
206 | union cvmx_ciu3_intr_ram_ecc_st { | ||
207 | uint64_t u64; | ||
208 | struct cvmx_ciu3_intr_ram_ecc_st_s { | ||
209 | #ifdef __BIG_ENDIAN_BITFIELD | ||
210 | uint64_t reserved_52_63 : 12; | ||
211 | uint64_t addr : 20; | ||
212 | uint64_t reserved_6_31 : 26; | ||
213 | uint64_t sisc_dbe : 1; | ||
214 | uint64_t sisc_sbe : 1; | ||
215 | uint64_t idt_dbe : 1; | ||
216 | uint64_t idt_sbe : 1; | ||
217 | uint64_t isc_dbe : 1; | ||
218 | uint64_t isc_sbe : 1; | ||
219 | #else | ||
220 | uint64_t isc_sbe : 1; | ||
221 | uint64_t isc_dbe : 1; | ||
222 | uint64_t idt_sbe : 1; | ||
223 | uint64_t idt_dbe : 1; | ||
224 | uint64_t sisc_sbe : 1; | ||
225 | uint64_t sisc_dbe : 1; | ||
226 | uint64_t reserved_6_31 : 26; | ||
227 | uint64_t addr : 20; | ||
228 | uint64_t reserved_52_63 : 12; | ||
229 | #endif | ||
230 | } s; | ||
231 | }; | ||
232 | |||
233 | union cvmx_ciu3_intr_ready { | ||
234 | uint64_t u64; | ||
235 | struct cvmx_ciu3_intr_ready_s { | ||
236 | #ifdef __BIG_ENDIAN_BITFIELD | ||
237 | uint64_t reserved_46_63 : 18; | ||
238 | uint64_t index : 14; | ||
239 | uint64_t reserved_1_31 : 31; | ||
240 | uint64_t ready : 1; | ||
241 | #else | ||
242 | uint64_t ready : 1; | ||
243 | uint64_t reserved_1_31 : 31; | ||
244 | uint64_t index : 14; | ||
245 | uint64_t reserved_46_63 : 18; | ||
246 | #endif | ||
247 | } s; | ||
248 | }; | ||
249 | |||
250 | union cvmx_ciu3_intr_slowdown { | ||
251 | uint64_t u64; | ||
252 | struct cvmx_ciu3_intr_slowdown_s { | ||
253 | #ifdef __BIG_ENDIAN_BITFIELD | ||
254 | uint64_t reserved_3_63 : 61; | ||
255 | uint64_t ctl : 3; | ||
256 | #else | ||
257 | uint64_t ctl : 3; | ||
258 | uint64_t reserved_3_63 : 61; | ||
259 | #endif | ||
260 | } s; | ||
261 | }; | ||
262 | |||
263 | union cvmx_ciu3_iscx_ctl { | ||
264 | uint64_t u64; | ||
265 | struct cvmx_ciu3_iscx_ctl_s { | ||
266 | #ifdef __BIG_ENDIAN_BITFIELD | ||
267 | uint64_t reserved_24_63 : 40; | ||
268 | uint64_t idt : 8; | ||
269 | uint64_t imp : 1; | ||
270 | uint64_t reserved_2_14 : 13; | ||
271 | uint64_t en : 1; | ||
272 | uint64_t raw : 1; | ||
273 | #else | ||
274 | uint64_t raw : 1; | ||
275 | uint64_t en : 1; | ||
276 | uint64_t reserved_2_14 : 13; | ||
277 | uint64_t imp : 1; | ||
278 | uint64_t idt : 8; | ||
279 | uint64_t reserved_24_63 : 40; | ||
280 | #endif | ||
281 | } s; | ||
282 | }; | ||
283 | |||
284 | union cvmx_ciu3_iscx_w1c { | ||
285 | uint64_t u64; | ||
286 | struct cvmx_ciu3_iscx_w1c_s { | ||
287 | #ifdef __BIG_ENDIAN_BITFIELD | ||
288 | uint64_t reserved_2_63 : 62; | ||
289 | uint64_t en : 1; | ||
290 | uint64_t raw : 1; | ||
291 | #else | ||
292 | uint64_t raw : 1; | ||
293 | uint64_t en : 1; | ||
294 | uint64_t reserved_2_63 : 62; | ||
295 | #endif | ||
296 | } s; | ||
297 | }; | ||
298 | |||
299 | union cvmx_ciu3_iscx_w1s { | ||
300 | uint64_t u64; | ||
301 | struct cvmx_ciu3_iscx_w1s_s { | ||
302 | #ifdef __BIG_ENDIAN_BITFIELD | ||
303 | uint64_t reserved_2_63 : 62; | ||
304 | uint64_t en : 1; | ||
305 | uint64_t raw : 1; | ||
306 | #else | ||
307 | uint64_t raw : 1; | ||
308 | uint64_t en : 1; | ||
309 | uint64_t reserved_2_63 : 62; | ||
310 | #endif | ||
311 | } s; | ||
312 | }; | ||
313 | |||
314 | union cvmx_ciu3_nmi { | ||
315 | uint64_t u64; | ||
316 | struct cvmx_ciu3_nmi_s { | ||
317 | #ifdef __BIG_ENDIAN_BITFIELD | ||
318 | uint64_t reserved_48_63 : 16; | ||
319 | uint64_t nmi : 48; | ||
320 | #else | ||
321 | uint64_t nmi : 48; | ||
322 | uint64_t reserved_48_63 : 16; | ||
323 | #endif | ||
324 | } s; | ||
325 | }; | ||
326 | |||
327 | union cvmx_ciu3_siscx { | ||
328 | uint64_t u64; | ||
329 | struct cvmx_ciu3_siscx_s { | ||
330 | #ifdef __BIG_ENDIAN_BITFIELD | ||
331 | uint64_t en : 64; | ||
332 | #else | ||
333 | uint64_t en : 64; | ||
334 | #endif | ||
335 | } s; | ||
336 | }; | ||
337 | |||
338 | union cvmx_ciu3_timx { | ||
339 | uint64_t u64; | ||
340 | struct cvmx_ciu3_timx_s { | ||
341 | #ifdef __BIG_ENDIAN_BITFIELD | ||
342 | uint64_t reserved_37_63 : 27; | ||
343 | uint64_t one_shot : 1; | ||
344 | uint64_t len : 36; | ||
345 | #else | ||
346 | uint64_t len : 36; | ||
347 | uint64_t one_shot : 1; | ||
348 | uint64_t reserved_37_63 : 27; | ||
349 | #endif | ||
350 | } s; | ||
351 | }; | ||
352 | |||
353 | #endif | ||
diff --git a/arch/mips/include/asm/octeon/cvmx-coremask.h b/arch/mips/include/asm/octeon/cvmx-coremask.h new file mode 100644 index 000000000000..097dc096db84 --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-coremask.h | |||
@@ -0,0 +1,89 @@ | |||
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) 2016 Cavium Inc. (support@cavium.com). | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * Module to support operations on bitmap of cores. Coremask can be used to | ||
12 | * select a specific core, a group of cores, or all available cores, for | ||
13 | * initialization and differentiation of roles within a single shared binary | ||
14 | * executable image. | ||
15 | * | ||
16 | * The core numbers used in this file are the same value as what is found in | ||
17 | * the COP0_EBASE register and the rdhwr 0 instruction. | ||
18 | * | ||
19 | * For the CN78XX and other multi-node environments the core numbers are not | ||
20 | * contiguous. The core numbers for the CN78XX are as follows: | ||
21 | * | ||
22 | * Node 0: Cores 0 - 47 | ||
23 | * Node 1: Cores 128 - 175 | ||
24 | * Node 2: Cores 256 - 303 | ||
25 | * Node 3: Cores 384 - 431 | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #ifndef __CVMX_COREMASK_H__ | ||
30 | #define __CVMX_COREMASK_H__ | ||
31 | |||
32 | #define CVMX_MIPS_MAX_CORES 1024 | ||
33 | /* bits per holder */ | ||
34 | #define CVMX_COREMASK_ELTSZ 64 | ||
35 | |||
36 | /* cvmx_coremask_t's size in u64 */ | ||
37 | #define CVMX_COREMASK_BMPSZ (CVMX_MIPS_MAX_CORES / CVMX_COREMASK_ELTSZ) | ||
38 | |||
39 | |||
40 | /* cvmx_coremask_t */ | ||
41 | struct cvmx_coremask { | ||
42 | u64 coremask_bitmap[CVMX_COREMASK_BMPSZ]; | ||
43 | }; | ||
44 | |||
45 | /* | ||
46 | * Is ``core'' set in the coremask? | ||
47 | */ | ||
48 | static inline bool cvmx_coremask_is_core_set(const struct cvmx_coremask *pcm, | ||
49 | int core) | ||
50 | { | ||
51 | int n, i; | ||
52 | |||
53 | n = core % CVMX_COREMASK_ELTSZ; | ||
54 | i = core / CVMX_COREMASK_ELTSZ; | ||
55 | |||
56 | return (pcm->coremask_bitmap[i] & ((u64)1 << n)) != 0; | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * Make a copy of a coremask | ||
61 | */ | ||
62 | static inline void cvmx_coremask_copy(struct cvmx_coremask *dest, | ||
63 | const struct cvmx_coremask *src) | ||
64 | { | ||
65 | memcpy(dest, src, sizeof(*dest)); | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * Set the lower 64-bit of the coremask. | ||
70 | */ | ||
71 | static inline void cvmx_coremask_set64(struct cvmx_coremask *pcm, | ||
72 | uint64_t coremask_64) | ||
73 | { | ||
74 | pcm->coremask_bitmap[0] = coremask_64; | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * Clear ``core'' from the coremask. | ||
79 | */ | ||
80 | static inline void cvmx_coremask_clear_core(struct cvmx_coremask *pcm, int core) | ||
81 | { | ||
82 | int n, i; | ||
83 | |||
84 | n = core % CVMX_COREMASK_ELTSZ; | ||
85 | i = core / CVMX_COREMASK_ELTSZ; | ||
86 | pcm->coremask_bitmap[i] &= ~(1ull << n); | ||
87 | } | ||
88 | |||
89 | #endif /* __CVMX_COREMASK_H__ */ | ||
diff --git a/arch/mips/include/asm/octeon/cvmx-fpa-defs.h b/arch/mips/include/asm/octeon/cvmx-fpa-defs.h index 1d79e3c7040d..887ff8e1f715 100644 --- a/arch/mips/include/asm/octeon/cvmx-fpa-defs.h +++ b/arch/mips/include/asm/octeon/cvmx-fpa-defs.h | |||
@@ -66,6 +66,7 @@ | |||
66 | #define CVMX_FPA_WART_CTL (CVMX_ADD_IO_SEG(0x00011800280000D8ull)) | 66 | #define CVMX_FPA_WART_CTL (CVMX_ADD_IO_SEG(0x00011800280000D8ull)) |
67 | #define CVMX_FPA_WART_STATUS (CVMX_ADD_IO_SEG(0x00011800280000E0ull)) | 67 | #define CVMX_FPA_WART_STATUS (CVMX_ADD_IO_SEG(0x00011800280000E0ull)) |
68 | #define CVMX_FPA_WQE_THRESHOLD (CVMX_ADD_IO_SEG(0x0001180028000468ull)) | 68 | #define CVMX_FPA_WQE_THRESHOLD (CVMX_ADD_IO_SEG(0x0001180028000468ull)) |
69 | #define CVMX_FPA_CLK_COUNT (CVMX_ADD_IO_SEG(0x00012800000000F0ull)) | ||
69 | 70 | ||
70 | union cvmx_fpa_addr_range_error { | 71 | union cvmx_fpa_addr_range_error { |
71 | uint64_t u64; | 72 | uint64_t u64; |
diff --git a/arch/mips/include/asm/octeon/cvmx-mio-defs.h b/arch/mips/include/asm/octeon/cvmx-mio-defs.h index bb0ae338a460..5196c04eee41 100644 --- a/arch/mips/include/asm/octeon/cvmx-mio-defs.h +++ b/arch/mips/include/asm/octeon/cvmx-mio-defs.h | |||
@@ -1481,7 +1481,9 @@ union cvmx_mio_fus_dat2 { | |||
1481 | uint64_t u64; | 1481 | uint64_t u64; |
1482 | struct cvmx_mio_fus_dat2_s { | 1482 | struct cvmx_mio_fus_dat2_s { |
1483 | #ifdef __BIG_ENDIAN_BITFIELD | 1483 | #ifdef __BIG_ENDIAN_BITFIELD |
1484 | uint64_t reserved_48_63:16; | 1484 | uint64_t reserved_59_63:5; |
1485 | uint64_t run_platform:3; | ||
1486 | uint64_t gbl_pwr_throttle:8; | ||
1485 | uint64_t fus118:1; | 1487 | uint64_t fus118:1; |
1486 | uint64_t rom_info:10; | 1488 | uint64_t rom_info:10; |
1487 | uint64_t power_limit:2; | 1489 | uint64_t power_limit:2; |
@@ -1513,7 +1515,9 @@ union cvmx_mio_fus_dat2 { | |||
1513 | uint64_t power_limit:2; | 1515 | uint64_t power_limit:2; |
1514 | uint64_t rom_info:10; | 1516 | uint64_t rom_info:10; |
1515 | uint64_t fus118:1; | 1517 | uint64_t fus118:1; |
1516 | uint64_t reserved_48_63:16; | 1518 | uint64_t gbl_pwr_throttle:8; |
1519 | uint64_t run_platform:3; | ||
1520 | uint64_t reserved_59_63:5; | ||
1517 | #endif | 1521 | #endif |
1518 | } s; | 1522 | } s; |
1519 | struct cvmx_mio_fus_dat2_cn30xx { | 1523 | struct cvmx_mio_fus_dat2_cn30xx { |
@@ -1837,50 +1841,192 @@ union cvmx_mio_fus_dat2 { | |||
1837 | #endif | 1841 | #endif |
1838 | } cn68xx; | 1842 | } cn68xx; |
1839 | struct cvmx_mio_fus_dat2_cn68xx cn68xxp1; | 1843 | struct cvmx_mio_fus_dat2_cn68xx cn68xxp1; |
1844 | struct cvmx_mio_fus_dat2_cn70xx { | ||
1845 | #ifdef __BIG_ENDIAN_BITFIELD | ||
1846 | uint64_t reserved_48_63:16; | ||
1847 | uint64_t fus118:1; | ||
1848 | uint64_t rom_info:10; | ||
1849 | uint64_t power_limit:2; | ||
1850 | uint64_t dorm_crypto:1; | ||
1851 | uint64_t fus318:1; | ||
1852 | uint64_t raid_en:1; | ||
1853 | uint64_t reserved_31_29:3; | ||
1854 | uint64_t nodfa_cp2:1; | ||
1855 | uint64_t nomul:1; | ||
1856 | uint64_t nocrypto:1; | ||
1857 | uint64_t reserved_25_24:2; | ||
1858 | uint64_t chip_id:8; | ||
1859 | uint64_t reserved_15_0:16; | ||
1860 | #else | ||
1861 | uint64_t reserved_15_0:16; | ||
1862 | uint64_t chip_id:8; | ||
1863 | uint64_t reserved_25_24:2; | ||
1864 | uint64_t nocrypto:1; | ||
1865 | uint64_t nomul:1; | ||
1866 | uint64_t nodfa_cp2:1; | ||
1867 | uint64_t reserved_31_29:3; | ||
1868 | uint64_t raid_en:1; | ||
1869 | uint64_t fus318:1; | ||
1870 | uint64_t dorm_crypto:1; | ||
1871 | uint64_t power_limit:2; | ||
1872 | uint64_t rom_info:10; | ||
1873 | uint64_t fus118:1; | ||
1874 | uint64_t reserved_48_63:16; | ||
1875 | #endif | ||
1876 | } cn70xx; | ||
1877 | struct cvmx_mio_fus_dat2_cn70xx cn70xxp1; | ||
1878 | struct cvmx_mio_fus_dat2_cn73xx { | ||
1879 | #ifdef __BIG_ENDIAN_BITFIELD | ||
1880 | uint64_t reserved_59_63:5; | ||
1881 | uint64_t run_platform:3; | ||
1882 | uint64_t gbl_pwr_throttle:8; | ||
1883 | uint64_t fus118:1; | ||
1884 | uint64_t rom_info:10; | ||
1885 | uint64_t power_limit:2; | ||
1886 | uint64_t dorm_crypto:1; | ||
1887 | uint64_t fus318:1; | ||
1888 | uint64_t raid_en:1; | ||
1889 | uint64_t reserved_31_29:3; | ||
1890 | uint64_t nodfa_cp2:1; | ||
1891 | uint64_t nomul:1; | ||
1892 | uint64_t nocrypto:1; | ||
1893 | uint64_t reserved_25_24:2; | ||
1894 | uint64_t chip_id:8; | ||
1895 | uint64_t reserved_15_0:16; | ||
1896 | #else | ||
1897 | uint64_t reserved_15_0:16; | ||
1898 | uint64_t chip_id:8; | ||
1899 | uint64_t reserved_25_24:2; | ||
1900 | uint64_t nocrypto:1; | ||
1901 | uint64_t nomul:1; | ||
1902 | uint64_t nodfa_cp2:1; | ||
1903 | uint64_t reserved_31_29:3; | ||
1904 | uint64_t raid_en:1; | ||
1905 | uint64_t fus318:1; | ||
1906 | uint64_t dorm_crypto:1; | ||
1907 | uint64_t power_limit:2; | ||
1908 | uint64_t rom_info:10; | ||
1909 | uint64_t fus118:1; | ||
1910 | uint64_t gbl_pwr_throttle:8; | ||
1911 | uint64_t run_platform:3; | ||
1912 | uint64_t reserved_59_63:5; | ||
1913 | #endif | ||
1914 | } cn73xx; | ||
1915 | struct cvmx_mio_fus_dat2_cn78xx { | ||
1916 | #ifdef __BIG_ENDIAN_BITFIELD | ||
1917 | uint64_t reserved_59_63:5; | ||
1918 | uint64_t run_platform:3; | ||
1919 | uint64_t reserved_48_55:8; | ||
1920 | uint64_t fus118:1; | ||
1921 | uint64_t rom_info:10; | ||
1922 | uint64_t power_limit:2; | ||
1923 | uint64_t dorm_crypto:1; | ||
1924 | uint64_t fus318:1; | ||
1925 | uint64_t raid_en:1; | ||
1926 | uint64_t reserved_31_29:3; | ||
1927 | uint64_t nodfa_cp2:1; | ||
1928 | uint64_t nomul:1; | ||
1929 | uint64_t nocrypto:1; | ||
1930 | uint64_t reserved_25_24:2; | ||
1931 | uint64_t chip_id:8; | ||
1932 | uint64_t reserved_0_15:16; | ||
1933 | #else | ||
1934 | uint64_t reserved_0_15:16; | ||
1935 | uint64_t chip_id:8; | ||
1936 | uint64_t reserved_25_24:2; | ||
1937 | uint64_t nocrypto:1; | ||
1938 | uint64_t nomul:1; | ||
1939 | uint64_t nodfa_cp2:1; | ||
1940 | uint64_t reserved_31_29:3; | ||
1941 | uint64_t raid_en:1; | ||
1942 | uint64_t fus318:1; | ||
1943 | uint64_t dorm_crypto:1; | ||
1944 | uint64_t power_limit:2; | ||
1945 | uint64_t rom_info:10; | ||
1946 | uint64_t fus118:1; | ||
1947 | uint64_t reserved_48_55:8; | ||
1948 | uint64_t run_platform:3; | ||
1949 | uint64_t reserved_59_63:5; | ||
1950 | #endif | ||
1951 | } cn78xx; | ||
1952 | struct cvmx_mio_fus_dat2_cn78xxp2 { | ||
1953 | #ifdef __BIG_ENDIAN_BITFIELD | ||
1954 | uint64_t reserved_59_63:5; | ||
1955 | uint64_t run_platform:3; | ||
1956 | uint64_t gbl_pwr_throttle:8; | ||
1957 | uint64_t fus118:1; | ||
1958 | uint64_t rom_info:10; | ||
1959 | uint64_t power_limit:2; | ||
1960 | uint64_t dorm_crypto:1; | ||
1961 | uint64_t fus318:1; | ||
1962 | uint64_t raid_en:1; | ||
1963 | uint64_t reserved_31_29:3; | ||
1964 | uint64_t nodfa_cp2:1; | ||
1965 | uint64_t nomul:1; | ||
1966 | uint64_t nocrypto:1; | ||
1967 | uint64_t reserved_25_24:2; | ||
1968 | uint64_t chip_id:8; | ||
1969 | uint64_t reserved_0_15:16; | ||
1970 | #else | ||
1971 | uint64_t reserved_0_15:16; | ||
1972 | uint64_t chip_id:8; | ||
1973 | uint64_t reserved_25_24:2; | ||
1974 | uint64_t nocrypto:1; | ||
1975 | uint64_t nomul:1; | ||
1976 | uint64_t nodfa_cp2:1; | ||
1977 | uint64_t reserved_31_29:3; | ||
1978 | uint64_t raid_en:1; | ||
1979 | uint64_t fus318:1; | ||
1980 | uint64_t dorm_crypto:1; | ||
1981 | uint64_t power_limit:2; | ||
1982 | uint64_t rom_info:10; | ||
1983 | uint64_t fus118:1; | ||
1984 | uint64_t gbl_pwr_throttle:8; | ||
1985 | uint64_t run_platform:3; | ||
1986 | uint64_t reserved_59_63:5; | ||
1987 | #endif | ||
1988 | } cn78xxp2; | ||
1840 | struct cvmx_mio_fus_dat2_cn61xx cnf71xx; | 1989 | struct cvmx_mio_fus_dat2_cn61xx cnf71xx; |
1990 | struct cvmx_mio_fus_dat2_cn73xx cnf75xx; | ||
1841 | }; | 1991 | }; |
1842 | 1992 | ||
1843 | union cvmx_mio_fus_dat3 { | 1993 | union cvmx_mio_fus_dat3 { |
1844 | uint64_t u64; | 1994 | uint64_t u64; |
1845 | struct cvmx_mio_fus_dat3_s { | 1995 | struct cvmx_mio_fus_dat3_s { |
1846 | #ifdef __BIG_ENDIAN_BITFIELD | 1996 | #ifdef __BIG_ENDIAN_BITFIELD |
1847 | uint64_t reserved_58_63:6; | 1997 | uint64_t ema0:6; |
1848 | uint64_t pll_ctl:10; | 1998 | uint64_t pll_ctl:10; |
1849 | uint64_t dfa_info_dte:3; | 1999 | uint64_t dfa_info_dte:3; |
1850 | uint64_t dfa_info_clm:4; | 2000 | uint64_t dfa_info_clm:4; |
1851 | uint64_t reserved_40_40:1; | 2001 | uint64_t pll_alt_matrix:1; |
1852 | uint64_t ema:2; | 2002 | uint64_t reserved_38_39:2; |
1853 | uint64_t efus_lck_rsv:1; | 2003 | uint64_t efus_lck_rsv:1; |
1854 | uint64_t efus_lck_man:1; | 2004 | uint64_t efus_lck_man:1; |
1855 | uint64_t pll_half_dis:1; | 2005 | uint64_t pll_half_dis:1; |
1856 | uint64_t l2c_crip:3; | 2006 | uint64_t l2c_crip:3; |
1857 | uint64_t pll_div4:1; | 2007 | uint64_t reserved_28_31:4; |
1858 | uint64_t reserved_29_30:2; | ||
1859 | uint64_t bar2_en:1; | ||
1860 | uint64_t efus_lck:1; | 2008 | uint64_t efus_lck:1; |
1861 | uint64_t efus_ign:1; | 2009 | uint64_t efus_ign:1; |
1862 | uint64_t nozip:1; | 2010 | uint64_t nozip:1; |
1863 | uint64_t nodfa_dte:1; | 2011 | uint64_t nodfa_dte:1; |
1864 | uint64_t icache:24; | 2012 | uint64_t reserved_0_23:24; |
1865 | #else | 2013 | #else |
1866 | uint64_t icache:24; | 2014 | uint64_t reserved_0_23:24; |
1867 | uint64_t nodfa_dte:1; | 2015 | uint64_t nodfa_dte:1; |
1868 | uint64_t nozip:1; | 2016 | uint64_t nozip:1; |
1869 | uint64_t efus_ign:1; | 2017 | uint64_t efus_ign:1; |
1870 | uint64_t efus_lck:1; | 2018 | uint64_t efus_lck:1; |
1871 | uint64_t bar2_en:1; | 2019 | uint64_t reserved_28_31:4; |
1872 | uint64_t reserved_29_30:2; | ||
1873 | uint64_t pll_div4:1; | ||
1874 | uint64_t l2c_crip:3; | 2020 | uint64_t l2c_crip:3; |
1875 | uint64_t pll_half_dis:1; | 2021 | uint64_t pll_half_dis:1; |
1876 | uint64_t efus_lck_man:1; | 2022 | uint64_t efus_lck_man:1; |
1877 | uint64_t efus_lck_rsv:1; | 2023 | uint64_t efus_lck_rsv:1; |
1878 | uint64_t ema:2; | 2024 | uint64_t reserved_38_39:2; |
1879 | uint64_t reserved_40_40:1; | 2025 | uint64_t pll_alt_matrix:1; |
1880 | uint64_t dfa_info_clm:4; | 2026 | uint64_t dfa_info_clm:4; |
1881 | uint64_t dfa_info_dte:3; | 2027 | uint64_t dfa_info_dte:3; |
1882 | uint64_t pll_ctl:10; | 2028 | uint64_t pll_ctl:10; |
1883 | uint64_t reserved_58_63:6; | 2029 | uint64_t ema0:6; |
1884 | #endif | 2030 | #endif |
1885 | } s; | 2031 | } s; |
1886 | struct cvmx_mio_fus_dat3_cn30xx { | 2032 | struct cvmx_mio_fus_dat3_cn30xx { |
@@ -2022,7 +2168,239 @@ union cvmx_mio_fus_dat3 { | |||
2022 | struct cvmx_mio_fus_dat3_cn61xx cn66xx; | 2168 | struct cvmx_mio_fus_dat3_cn61xx cn66xx; |
2023 | struct cvmx_mio_fus_dat3_cn61xx cn68xx; | 2169 | struct cvmx_mio_fus_dat3_cn61xx cn68xx; |
2024 | struct cvmx_mio_fus_dat3_cn61xx cn68xxp1; | 2170 | struct cvmx_mio_fus_dat3_cn61xx cn68xxp1; |
2171 | struct cvmx_mio_fus_dat3_cn70xx { | ||
2172 | #ifdef __BIG_ENDIAN_BITFIELD | ||
2173 | uint64_t ema0:6; | ||
2174 | uint64_t pll_ctl:10; | ||
2175 | uint64_t dfa_info_dte:3; | ||
2176 | uint64_t dfa_info_clm:4; | ||
2177 | uint64_t pll_alt_matrix:1; | ||
2178 | uint64_t pll_bwadj_denom:2; | ||
2179 | uint64_t efus_lck_rsv:1; | ||
2180 | uint64_t efus_lck_man:1; | ||
2181 | uint64_t pll_half_dis:1; | ||
2182 | uint64_t l2c_crip:3; | ||
2183 | uint64_t use_int_refclk:1; | ||
2184 | uint64_t zip_info:2; | ||
2185 | uint64_t bar2_sz_conf:1; | ||
2186 | uint64_t efus_lck:1; | ||
2187 | uint64_t efus_ign:1; | ||
2188 | uint64_t nozip:1; | ||
2189 | uint64_t nodfa_dte:1; | ||
2190 | uint64_t ema1:6; | ||
2191 | uint64_t reserved_0_17:18; | ||
2192 | #else | ||
2193 | uint64_t reserved_0_17:18; | ||
2194 | uint64_t ema1:6; | ||
2195 | uint64_t nodfa_dte:1; | ||
2196 | uint64_t nozip:1; | ||
2197 | uint64_t efus_ign:1; | ||
2198 | uint64_t efus_lck:1; | ||
2199 | uint64_t bar2_sz_conf:1; | ||
2200 | uint64_t zip_info:2; | ||
2201 | uint64_t use_int_refclk:1; | ||
2202 | uint64_t l2c_crip:3; | ||
2203 | uint64_t pll_half_dis:1; | ||
2204 | uint64_t efus_lck_man:1; | ||
2205 | uint64_t efus_lck_rsv:1; | ||
2206 | uint64_t pll_bwadj_denom:2; | ||
2207 | uint64_t pll_alt_matrix:1; | ||
2208 | uint64_t dfa_info_clm:4; | ||
2209 | uint64_t dfa_info_dte:3; | ||
2210 | uint64_t pll_ctl:10; | ||
2211 | uint64_t ema0:6; | ||
2212 | #endif | ||
2213 | } cn70xx; | ||
2214 | struct cvmx_mio_fus_dat3_cn70xxp1 { | ||
2215 | #ifdef __BIG_ENDIAN_BITFIELD | ||
2216 | uint64_t ema0:6; | ||
2217 | uint64_t pll_ctl:10; | ||
2218 | uint64_t dfa_info_dte:3; | ||
2219 | uint64_t dfa_info_clm:4; | ||
2220 | uint64_t reserved_38_40:3; | ||
2221 | uint64_t efus_lck_rsv:1; | ||
2222 | uint64_t efus_lck_man:1; | ||
2223 | uint64_t pll_half_dis:1; | ||
2224 | uint64_t l2c_crip:3; | ||
2225 | uint64_t reserved_31_31:1; | ||
2226 | uint64_t zip_info:2; | ||
2227 | uint64_t bar2_sz_conf:1; | ||
2228 | uint64_t efus_lck:1; | ||
2229 | uint64_t efus_ign:1; | ||
2230 | uint64_t nozip:1; | ||
2231 | uint64_t nodfa_dte:1; | ||
2232 | uint64_t ema1:6; | ||
2233 | uint64_t reserved_0_17:18; | ||
2234 | #else | ||
2235 | uint64_t reserved_0_17:18; | ||
2236 | uint64_t ema1:6; | ||
2237 | uint64_t nodfa_dte:1; | ||
2238 | uint64_t nozip:1; | ||
2239 | uint64_t efus_ign:1; | ||
2240 | uint64_t efus_lck:1; | ||
2241 | uint64_t bar2_sz_conf:1; | ||
2242 | uint64_t zip_info:2; | ||
2243 | uint64_t reserved_31_31:1; | ||
2244 | uint64_t l2c_crip:3; | ||
2245 | uint64_t pll_half_dis:1; | ||
2246 | uint64_t efus_lck_man:1; | ||
2247 | uint64_t efus_lck_rsv:1; | ||
2248 | uint64_t reserved_38_40:3; | ||
2249 | uint64_t dfa_info_clm:4; | ||
2250 | uint64_t dfa_info_dte:3; | ||
2251 | uint64_t pll_ctl:10; | ||
2252 | uint64_t ema0:6; | ||
2253 | #endif | ||
2254 | } cn70xxp1; | ||
2255 | struct cvmx_mio_fus_dat3_cn73xx { | ||
2256 | #ifdef __BIG_ENDIAN_BITFIELD | ||
2257 | uint64_t ema0:6; | ||
2258 | uint64_t pll_ctl:10; | ||
2259 | uint64_t dfa_info_dte:3; | ||
2260 | uint64_t dfa_info_clm:4; | ||
2261 | uint64_t pll_alt_matrix:1; | ||
2262 | uint64_t pll_bwadj_denom:2; | ||
2263 | uint64_t efus_lck_rsv:1; | ||
2264 | uint64_t efus_lck_man:1; | ||
2265 | uint64_t pll_half_dis:1; | ||
2266 | uint64_t l2c_crip:3; | ||
2267 | uint64_t use_int_refclk:1; | ||
2268 | uint64_t zip_info:2; | ||
2269 | uint64_t bar2_sz_conf:1; | ||
2270 | uint64_t efus_lck:1; | ||
2271 | uint64_t efus_ign:1; | ||
2272 | uint64_t nozip:1; | ||
2273 | uint64_t nodfa_dte:1; | ||
2274 | uint64_t ema1:6; | ||
2275 | uint64_t nohna_dte:1; | ||
2276 | uint64_t hna_info_dte:3; | ||
2277 | uint64_t hna_info_clm:4; | ||
2278 | uint64_t reserved_9_9:1; | ||
2279 | uint64_t core_pll_mul:5; | ||
2280 | uint64_t pnr_pll_mul:4; | ||
2281 | #else | ||
2282 | uint64_t pnr_pll_mul:4; | ||
2283 | uint64_t core_pll_mul:5; | ||
2284 | uint64_t reserved_9_9:1; | ||
2285 | uint64_t hna_info_clm:4; | ||
2286 | uint64_t hna_info_dte:3; | ||
2287 | uint64_t nohna_dte:1; | ||
2288 | uint64_t ema1:6; | ||
2289 | uint64_t nodfa_dte:1; | ||
2290 | uint64_t nozip:1; | ||
2291 | uint64_t efus_ign:1; | ||
2292 | uint64_t efus_lck:1; | ||
2293 | uint64_t bar2_sz_conf:1; | ||
2294 | uint64_t zip_info:2; | ||
2295 | uint64_t use_int_refclk:1; | ||
2296 | uint64_t l2c_crip:3; | ||
2297 | uint64_t pll_half_dis:1; | ||
2298 | uint64_t efus_lck_man:1; | ||
2299 | uint64_t efus_lck_rsv:1; | ||
2300 | uint64_t pll_bwadj_denom:2; | ||
2301 | uint64_t pll_alt_matrix:1; | ||
2302 | uint64_t dfa_info_clm:4; | ||
2303 | uint64_t dfa_info_dte:3; | ||
2304 | uint64_t pll_ctl:10; | ||
2305 | uint64_t ema0:6; | ||
2306 | #endif | ||
2307 | } cn73xx; | ||
2308 | struct cvmx_mio_fus_dat3_cn78xx { | ||
2309 | #ifdef __BIG_ENDIAN_BITFIELD | ||
2310 | uint64_t ema0:6; | ||
2311 | uint64_t pll_ctl:10; | ||
2312 | uint64_t dfa_info_dte:3; | ||
2313 | uint64_t dfa_info_clm:4; | ||
2314 | uint64_t reserved_38_40:3; | ||
2315 | uint64_t efus_lck_rsv:1; | ||
2316 | uint64_t efus_lck_man:1; | ||
2317 | uint64_t pll_half_dis:1; | ||
2318 | uint64_t l2c_crip:3; | ||
2319 | uint64_t reserved_31_31:1; | ||
2320 | uint64_t zip_info:2; | ||
2321 | uint64_t bar2_sz_conf:1; | ||
2322 | uint64_t efus_lck:1; | ||
2323 | uint64_t efus_ign:1; | ||
2324 | uint64_t nozip:1; | ||
2325 | uint64_t nodfa_dte:1; | ||
2326 | uint64_t ema1:6; | ||
2327 | uint64_t nohna_dte:1; | ||
2328 | uint64_t hna_info_dte:3; | ||
2329 | uint64_t hna_info_clm:4; | ||
2330 | uint64_t reserved_0_9:10; | ||
2331 | #else | ||
2332 | uint64_t reserved_0_9:10; | ||
2333 | uint64_t hna_info_clm:4; | ||
2334 | uint64_t hna_info_dte:3; | ||
2335 | uint64_t nohna_dte:1; | ||
2336 | uint64_t ema1:6; | ||
2337 | uint64_t nodfa_dte:1; | ||
2338 | uint64_t nozip:1; | ||
2339 | uint64_t efus_ign:1; | ||
2340 | uint64_t efus_lck:1; | ||
2341 | uint64_t bar2_sz_conf:1; | ||
2342 | uint64_t zip_info:2; | ||
2343 | uint64_t reserved_31_31:1; | ||
2344 | uint64_t l2c_crip:3; | ||
2345 | uint64_t pll_half_dis:1; | ||
2346 | uint64_t efus_lck_man:1; | ||
2347 | uint64_t efus_lck_rsv:1; | ||
2348 | uint64_t reserved_38_40:3; | ||
2349 | uint64_t dfa_info_clm:4; | ||
2350 | uint64_t dfa_info_dte:3; | ||
2351 | uint64_t pll_ctl:10; | ||
2352 | uint64_t ema0:6; | ||
2353 | #endif | ||
2354 | } cn78xx; | ||
2355 | struct cvmx_mio_fus_dat3_cn73xx cn78xxp2; | ||
2025 | struct cvmx_mio_fus_dat3_cn61xx cnf71xx; | 2356 | struct cvmx_mio_fus_dat3_cn61xx cnf71xx; |
2357 | struct cvmx_mio_fus_dat3_cnf75xx { | ||
2358 | #ifdef __BIG_ENDIAN_BITFIELD | ||
2359 | uint64_t ema0:6; | ||
2360 | uint64_t pll_ctl:10; | ||
2361 | uint64_t dfa_info_dte:3; | ||
2362 | uint64_t dfa_info_clm:4; | ||
2363 | uint64_t pll_alt_matrix:1; | ||
2364 | uint64_t pll_bwadj_denom:2; | ||
2365 | uint64_t efus_lck_rsv:1; | ||
2366 | uint64_t efus_lck_man:1; | ||
2367 | uint64_t pll_half_dis:1; | ||
2368 | uint64_t l2c_crip:3; | ||
2369 | uint64_t use_int_refclk:1; | ||
2370 | uint64_t zip_info:2; | ||
2371 | uint64_t bar2_sz_conf:1; | ||
2372 | uint64_t efus_lck:1; | ||
2373 | uint64_t efus_ign:1; | ||
2374 | uint64_t nozip:1; | ||
2375 | uint64_t nodfa_dte:1; | ||
2376 | uint64_t ema1:6; | ||
2377 | uint64_t reserved_9_17:9; | ||
2378 | uint64_t core_pll_mul:5; | ||
2379 | uint64_t pnr_pll_mul:4; | ||
2380 | #else | ||
2381 | uint64_t pnr_pll_mul:4; | ||
2382 | uint64_t core_pll_mul:5; | ||
2383 | uint64_t reserved_9_17:9; | ||
2384 | uint64_t ema1:6; | ||
2385 | uint64_t nodfa_dte:1; | ||
2386 | uint64_t nozip:1; | ||
2387 | uint64_t efus_ign:1; | ||
2388 | uint64_t efus_lck:1; | ||
2389 | uint64_t bar2_sz_conf:1; | ||
2390 | uint64_t zip_info:2; | ||
2391 | uint64_t use_int_refclk:1; | ||
2392 | uint64_t l2c_crip:3; | ||
2393 | uint64_t pll_half_dis:1; | ||
2394 | uint64_t efus_lck_man:1; | ||
2395 | uint64_t efus_lck_rsv:1; | ||
2396 | uint64_t pll_bwadj_denom:2; | ||
2397 | uint64_t pll_alt_matrix:1; | ||
2398 | uint64_t dfa_info_clm:4; | ||
2399 | uint64_t dfa_info_dte:3; | ||
2400 | uint64_t pll_ctl:10; | ||
2401 | uint64_t ema0:6; | ||
2402 | #endif | ||
2403 | } cnf75xx; | ||
2026 | }; | 2404 | }; |
2027 | 2405 | ||
2028 | union cvmx_mio_fus_ema { | 2406 | union cvmx_mio_fus_ema { |
diff --git a/arch/mips/include/asm/octeon/cvmx-sysinfo.h b/arch/mips/include/asm/octeon/cvmx-sysinfo.h index 2131197422e5..c6c3ee39c69d 100644 --- a/arch/mips/include/asm/octeon/cvmx-sysinfo.h +++ b/arch/mips/include/asm/octeon/cvmx-sysinfo.h | |||
@@ -4,7 +4,7 @@ | |||
4 | * Contact: support@caviumnetworks.com | 4 | * Contact: support@caviumnetworks.com |
5 | * This file is part of the OCTEON SDK | 5 | * This file is part of the OCTEON SDK |
6 | * | 6 | * |
7 | * Copyright (c) 2003-2008 Cavium Networks | 7 | * Copyright (c) 2003-2016 Cavium, Inc. |
8 | * | 8 | * |
9 | * This file is free software; you can redistribute it and/or modify | 9 | * This file is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License, Version 2, as | 10 | * it under the terms of the GNU General Public License, Version 2, as |
@@ -32,6 +32,8 @@ | |||
32 | #ifndef __CVMX_SYSINFO_H__ | 32 | #ifndef __CVMX_SYSINFO_H__ |
33 | #define __CVMX_SYSINFO_H__ | 33 | #define __CVMX_SYSINFO_H__ |
34 | 34 | ||
35 | #include "cvmx-coremask.h" | ||
36 | |||
35 | #define OCTEON_SERIAL_LEN 20 | 37 | #define OCTEON_SERIAL_LEN 20 |
36 | /** | 38 | /** |
37 | * Structure describing application specific information. | 39 | * Structure describing application specific information. |
@@ -50,8 +52,7 @@ struct cvmx_sysinfo { | |||
50 | uint64_t system_dram_size; | 52 | uint64_t system_dram_size; |
51 | 53 | ||
52 | /* ptr to memory descriptor block */ | 54 | /* ptr to memory descriptor block */ |
53 | void *phy_mem_desc_ptr; | 55 | uint64_t phy_mem_desc_addr; |
54 | |||
55 | 56 | ||
56 | /* Application image specific variables */ | 57 | /* Application image specific variables */ |
57 | /* stack top address (virtual) */ | 58 | /* stack top address (virtual) */ |
@@ -63,7 +64,7 @@ struct cvmx_sysinfo { | |||
63 | /* heap size in bytes */ | 64 | /* heap size in bytes */ |
64 | uint32_t heap_size; | 65 | uint32_t heap_size; |
65 | /* coremask defining cores running application */ | 66 | /* coremask defining cores running application */ |
66 | uint32_t core_mask; | 67 | struct cvmx_coremask core_mask; |
67 | /* Deprecated, use cvmx_coremask_first_core() to select init core */ | 68 | /* Deprecated, use cvmx_coremask_first_core() to select init core */ |
68 | uint32_t init_core; | 69 | uint32_t init_core; |
69 | 70 | ||
@@ -121,32 +122,4 @@ struct cvmx_sysinfo { | |||
121 | 122 | ||
122 | extern struct cvmx_sysinfo *cvmx_sysinfo_get(void); | 123 | extern struct cvmx_sysinfo *cvmx_sysinfo_get(void); |
123 | 124 | ||
124 | /** | ||
125 | * This function is used in non-simple executive environments (such as | ||
126 | * Linux kernel, u-boot, etc.) to configure the minimal fields that | ||
127 | * are required to use simple executive files directly. | ||
128 | * | ||
129 | * Locking (if required) must be handled outside of this | ||
130 | * function | ||
131 | * | ||
132 | * @phy_mem_desc_ptr: Pointer to global physical memory descriptor | ||
133 | * (bootmem descriptor) @board_type: Octeon board | ||
134 | * type enumeration | ||
135 | * | ||
136 | * @board_rev_major: | ||
137 | * Board major revision | ||
138 | * @board_rev_minor: | ||
139 | * Board minor revision | ||
140 | * @cpu_clock_hz: | ||
141 | * CPU clock freqency in hertz | ||
142 | * | ||
143 | * Returns 0: Failure | ||
144 | * 1: success | ||
145 | */ | ||
146 | extern int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr, | ||
147 | uint16_t board_type, | ||
148 | uint8_t board_rev_major, | ||
149 | uint8_t board_rev_minor, | ||
150 | uint32_t cpu_clock_hz); | ||
151 | |||
152 | #endif /* __CVMX_SYSINFO_H__ */ | 125 | #endif /* __CVMX_SYSINFO_H__ */ |
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index 3e982e0c397e..2530e8731c8a 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h | |||
@@ -57,6 +57,7 @@ enum cvmx_mips_space { | |||
57 | #include <asm/octeon/cvmx-sysinfo.h> | 57 | #include <asm/octeon/cvmx-sysinfo.h> |
58 | 58 | ||
59 | #include <asm/octeon/cvmx-ciu-defs.h> | 59 | #include <asm/octeon/cvmx-ciu-defs.h> |
60 | #include <asm/octeon/cvmx-ciu3-defs.h> | ||
60 | #include <asm/octeon/cvmx-gpio-defs.h> | 61 | #include <asm/octeon/cvmx-gpio-defs.h> |
61 | #include <asm/octeon/cvmx-iob-defs.h> | 62 | #include <asm/octeon/cvmx-iob-defs.h> |
62 | #include <asm/octeon/cvmx-ipd-defs.h> | 63 | #include <asm/octeon/cvmx-ipd-defs.h> |
@@ -341,6 +342,21 @@ static inline unsigned int cvmx_get_core_num(void) | |||
341 | return core_num; | 342 | return core_num; |
342 | } | 343 | } |
343 | 344 | ||
345 | /* Maximum # of bits to define core in node */ | ||
346 | #define CVMX_NODE_NO_SHIFT 7 | ||
347 | #define CVMX_NODE_MASK 0x3 | ||
348 | static inline unsigned int cvmx_get_node_num(void) | ||
349 | { | ||
350 | unsigned int core_num = cvmx_get_core_num(); | ||
351 | |||
352 | return (core_num >> CVMX_NODE_NO_SHIFT) & CVMX_NODE_MASK; | ||
353 | } | ||
354 | |||
355 | static inline unsigned int cvmx_get_local_core_num(void) | ||
356 | { | ||
357 | return cvmx_get_core_num() & ((1 << CVMX_NODE_NO_SHIFT) - 1); | ||
358 | } | ||
359 | |||
344 | /** | 360 | /** |
345 | * Returns the number of bits set in the provided value. | 361 | * Returns the number of bits set in the provided value. |
346 | * Simple wrapper for POP instruction. | 362 | * Simple wrapper for POP instruction. |
@@ -448,8 +464,15 @@ static inline uint64_t cvmx_get_cycle_global(void) | |||
448 | /* Return the number of cores available in the chip */ | 464 | /* Return the number of cores available in the chip */ |
449 | static inline uint32_t cvmx_octeon_num_cores(void) | 465 | static inline uint32_t cvmx_octeon_num_cores(void) |
450 | { | 466 | { |
451 | uint32_t ciu_fuse = (uint32_t) cvmx_read_csr(CVMX_CIU_FUSE) & 0xffff; | 467 | u64 ciu_fuse_reg; |
452 | return cvmx_pop(ciu_fuse); | 468 | u64 ciu_fuse; |
469 | |||
470 | if (OCTEON_IS_OCTEON3() && !OCTEON_IS_MODEL(OCTEON_CN70XX)) | ||
471 | ciu_fuse_reg = CVMX_CIU3_FUSE; | ||
472 | else | ||
473 | ciu_fuse_reg = CVMX_CIU_FUSE; | ||
474 | ciu_fuse = cvmx_read_csr(ciu_fuse_reg); | ||
475 | return cvmx_dpop(ciu_fuse); | ||
453 | } | 476 | } |
454 | 477 | ||
455 | #endif /* __CVMX_H__ */ | 478 | #endif /* __CVMX_H__ */ |
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h index 3ed10a8d7865..a19ca3b2775c 100644 --- a/arch/mips/include/asm/octeon/octeon-feature.h +++ b/arch/mips/include/asm/octeon/octeon-feature.h | |||
@@ -81,6 +81,10 @@ enum octeon_feature { | |||
81 | OCTEON_FEATURE_HFA, | 81 | OCTEON_FEATURE_HFA, |
82 | OCTEON_FEATURE_DFM, | 82 | OCTEON_FEATURE_DFM, |
83 | OCTEON_FEATURE_CIU2, | 83 | OCTEON_FEATURE_CIU2, |
84 | OCTEON_FEATURE_CIU3, | ||
85 | /* Octeon has FPA first seen on 78XX */ | ||
86 | OCTEON_FEATURE_FPA3, | ||
87 | OCTEON_FEATURE_FAU, | ||
84 | OCTEON_MAX_FEATURE | 88 | OCTEON_MAX_FEATURE |
85 | }; | 89 | }; |
86 | 90 | ||
@@ -110,7 +114,7 @@ static inline int octeon_has_crypto(void) | |||
110 | * Returns Non zero if the feature exists. Zero if the feature does not | 114 | * Returns Non zero if the feature exists. Zero if the feature does not |
111 | * exist. | 115 | * exist. |
112 | */ | 116 | */ |
113 | static inline int octeon_has_feature(enum octeon_feature feature) | 117 | static inline bool octeon_has_feature(enum octeon_feature feature) |
114 | { | 118 | { |
115 | switch (feature) { | 119 | switch (feature) { |
116 | case OCTEON_FEATURE_SAAD: | 120 | case OCTEON_FEATURE_SAAD: |
@@ -122,7 +126,7 @@ static inline int octeon_has_feature(enum octeon_feature feature) | |||
122 | fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); | 126 | fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); |
123 | return !fus_2.s.nocrypto && !fus_2.s.nomul && fus_2.s.dorm_crypto; | 127 | return !fus_2.s.nocrypto && !fus_2.s.nomul && fus_2.s.dorm_crypto; |
124 | } else { | 128 | } else { |
125 | return 0; | 129 | return false; |
126 | } | 130 | } |
127 | 131 | ||
128 | case OCTEON_FEATURE_PCIE: | 132 | case OCTEON_FEATURE_PCIE: |
@@ -190,11 +194,20 @@ static inline int octeon_has_feature(enum octeon_feature feature) | |||
190 | 194 | ||
191 | case OCTEON_FEATURE_CIU2: | 195 | case OCTEON_FEATURE_CIU2: |
192 | return OCTEON_IS_MODEL(OCTEON_CN68XX); | 196 | return OCTEON_IS_MODEL(OCTEON_CN68XX); |
197 | case OCTEON_FEATURE_CIU3: | ||
198 | case OCTEON_FEATURE_FPA3: | ||
199 | return OCTEON_IS_MODEL(OCTEON_CN78XX) | ||
200 | || OCTEON_IS_MODEL(OCTEON_CNF75XX) | ||
201 | || OCTEON_IS_MODEL(OCTEON_CN73XX); | ||
202 | case OCTEON_FEATURE_FAU: | ||
203 | return !(OCTEON_IS_MODEL(OCTEON_CN78XX) | ||
204 | || OCTEON_IS_MODEL(OCTEON_CNF75XX) | ||
205 | || OCTEON_IS_MODEL(OCTEON_CN73XX)); | ||
193 | 206 | ||
194 | default: | 207 | default: |
195 | break; | 208 | break; |
196 | } | 209 | } |
197 | return 0; | 210 | return false; |
198 | } | 211 | } |
199 | 212 | ||
200 | #endif /* __OCTEON_FEATURE_H__ */ | 213 | #endif /* __OCTEON_FEATURE_H__ */ |
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h index 92b377e36dac..6c68517c2770 100644 --- a/arch/mips/include/asm/octeon/octeon-model.h +++ b/arch/mips/include/asm/octeon/octeon-model.h | |||
@@ -74,7 +74,12 @@ | |||
74 | * CN7XXX models with new revision encoding | 74 | * CN7XXX models with new revision encoding |
75 | */ | 75 | */ |
76 | 76 | ||
77 | #define OCTEON_CNF75XX_PASS1_0 0x000d9800 | ||
78 | #define OCTEON_CNF75XX (OCTEON_CNF75XX_PASS1_0 | OM_IGNORE_REVISION) | ||
79 | #define OCTEON_CNF75XX_PASS1_X (OCTEON_CNF75XX_PASS1_0 | OM_IGNORE_MINOR_REVISION) | ||
80 | |||
77 | #define OCTEON_CN73XX_PASS1_0 0x000d9700 | 81 | #define OCTEON_CN73XX_PASS1_0 0x000d9700 |
82 | #define OCTEON_CN73XX_PASS1_1 0x000d9701 | ||
78 | #define OCTEON_CN73XX (OCTEON_CN73XX_PASS1_0 | OM_IGNORE_REVISION) | 83 | #define OCTEON_CN73XX (OCTEON_CN73XX_PASS1_0 | OM_IGNORE_REVISION) |
79 | #define OCTEON_CN73XX_PASS1_X (OCTEON_CN73XX_PASS1_0 | \ | 84 | #define OCTEON_CN73XX_PASS1_X (OCTEON_CN73XX_PASS1_0 | \ |
80 | OM_IGNORE_MINOR_REVISION) | 85 | OM_IGNORE_MINOR_REVISION) |
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h index de9f74ee5dd0..07c0516ef4d5 100644 --- a/arch/mips/include/asm/octeon/octeon.h +++ b/arch/mips/include/asm/octeon/octeon.h | |||
@@ -299,6 +299,31 @@ static inline void octeon_npi_write32(uint64_t address, uint32_t val) | |||
299 | cvmx_read64_uint32(address ^ 4); | 299 | cvmx_read64_uint32(address ^ 4); |
300 | } | 300 | } |
301 | 301 | ||
302 | #ifdef CONFIG_SMP | ||
303 | void octeon_setup_smp(void); | ||
304 | #else | ||
305 | static inline void octeon_setup_smp(void) {} | ||
306 | #endif | ||
307 | |||
308 | struct irq_domain; | ||
309 | struct device_node; | ||
310 | struct irq_data; | ||
311 | struct irq_chip; | ||
312 | void octeon_ciu3_mbox_send(int cpu, unsigned int mbox); | ||
313 | int octeon_irq_ciu3_xlat(struct irq_domain *d, | ||
314 | struct device_node *node, | ||
315 | const u32 *intspec, | ||
316 | unsigned int intsize, | ||
317 | unsigned long *out_hwirq, | ||
318 | unsigned int *out_type); | ||
319 | void octeon_irq_ciu3_enable(struct irq_data *data); | ||
320 | void octeon_irq_ciu3_disable(struct irq_data *data); | ||
321 | void octeon_irq_ciu3_ack(struct irq_data *data); | ||
322 | void octeon_irq_ciu3_mask(struct irq_data *data); | ||
323 | void octeon_irq_ciu3_mask_ack(struct irq_data *data); | ||
324 | int octeon_irq_ciu3_mapx(struct irq_domain *d, unsigned int virq, | ||
325 | irq_hw_number_t hw, struct irq_chip *chip); | ||
326 | |||
302 | /* Octeon multiplier save/restore routines from octeon_switch.S */ | 327 | /* Octeon multiplier save/restore routines from octeon_switch.S */ |
303 | void octeon_mult_save(void); | 328 | void octeon_mult_save(void); |
304 | void octeon_mult_restore(void); | 329 | void octeon_mult_restore(void); |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 8c16fb7b8fdb..86b239d9d75d 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
@@ -43,8 +43,6 @@ struct pci_controller { | |||
43 | and XFree86. Eventually will be removed. */ | 43 | and XFree86. Eventually will be removed. */ |
44 | unsigned int need_domain_info; | 44 | unsigned int need_domain_info; |
45 | 45 | ||
46 | int iommu; | ||
47 | |||
48 | /* Optional access methods for reading/writing the bus number | 46 | /* Optional access methods for reading/writing the bus number |
49 | of the PCI controller */ | 47 | of the PCI controller */ |
50 | int (*get_busno)(void); | 48 | int (*get_busno)(void); |
@@ -106,11 +104,11 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
106 | struct pci_dev; | 104 | struct pci_dev; |
107 | 105 | ||
108 | /* | 106 | /* |
109 | * The PCI address space does equal the physical memory address space. The | 107 | * The PCI address space does equal the physical memory address space. |
110 | * networking and block device layers use this boolean for bounce buffer | 108 | * The networking and block device layers use this boolean for bounce |
111 | * decisions. This is set if any hose does not have an IOMMU. | 109 | * buffer decisions. |
112 | */ | 110 | */ |
113 | extern unsigned int PCI_DMA_BUS_IS_PHYS; | 111 | #define PCI_DMA_BUS_IS_PHYS (1) |
114 | 112 | ||
115 | #ifdef CONFIG_PCI_DOMAINS | 113 | #ifdef CONFIG_PCI_DOMAINS |
116 | #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index | 114 | #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index |
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index 832e2167d00f..d21f3da7bdb6 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h | |||
@@ -103,8 +103,8 @@ static inline void pmd_clear(pmd_t *pmdp) | |||
103 | pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); | 103 | pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); |
104 | } | 104 | } |
105 | 105 | ||
106 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 106 | #if defined(CONFIG_XPA) |
107 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | 107 | |
108 | #define pte_pfn(x) (((unsigned long)((x).pte_high >> _PFN_SHIFT)) | (unsigned long)((x).pte_low << _PAGE_PRESENT_SHIFT)) | 108 | #define pte_pfn(x) (((unsigned long)((x).pte_high >> _PFN_SHIFT)) | (unsigned long)((x).pte_low << _PAGE_PRESENT_SHIFT)) |
109 | static inline pte_t | 109 | static inline pte_t |
110 | pfn_pte(unsigned long pfn, pgprot_t prot) | 110 | pfn_pte(unsigned long pfn, pgprot_t prot) |
@@ -118,9 +118,21 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
118 | return pte; | 118 | return pte; |
119 | } | 119 | } |
120 | 120 | ||
121 | #else | 121 | #elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
122 | 122 | ||
123 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | 123 | #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) |
124 | |||
125 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) | ||
126 | { | ||
127 | pte_t pte; | ||
128 | |||
129 | pte.pte_high = (pfn << 6) | (pgprot_val(prot) & 0x3f); | ||
130 | pte.pte_low = pgprot_val(prot); | ||
131 | |||
132 | return pte; | ||
133 | } | ||
134 | |||
135 | #else | ||
124 | 136 | ||
125 | #ifdef CONFIG_CPU_VR41XX | 137 | #ifdef CONFIG_CPU_VR41XX |
126 | #define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2))) | 138 | #define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2))) |
@@ -131,6 +143,8 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
131 | #endif | 143 | #endif |
132 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ | 144 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ |
133 | 145 | ||
146 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | ||
147 | |||
134 | #define __pgd_offset(address) pgd_index(address) | 148 | #define __pgd_offset(address) pgd_index(address) |
135 | #define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) | 149 | #define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) |
136 | #define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) | 150 | #define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) |
@@ -166,7 +180,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
166 | 180 | ||
167 | #else | 181 | #else |
168 | 182 | ||
169 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 183 | #if defined(CONFIG_XPA) |
170 | 184 | ||
171 | /* Swap entries must have VALID and GLOBAL bits cleared. */ | 185 | /* Swap entries must have VALID and GLOBAL bits cleared. */ |
172 | #define __swp_type(x) (((x).val >> 4) & 0x1f) | 186 | #define __swp_type(x) (((x).val >> 4) & 0x1f) |
@@ -175,6 +189,15 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
175 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) | 189 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) |
176 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) | 190 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) |
177 | 191 | ||
192 | #elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | ||
193 | |||
194 | /* Swap entries must have VALID and GLOBAL bits cleared. */ | ||
195 | #define __swp_type(x) (((x).val >> 2) & 0x1f) | ||
196 | #define __swp_offset(x) ((x).val >> 7) | ||
197 | #define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) | ||
198 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) | ||
199 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) | ||
200 | |||
178 | #else | 201 | #else |
179 | /* | 202 | /* |
180 | * Constraints: | 203 | * Constraints: |
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h index cf661a2fb141..514cbc0a6a67 100644 --- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <asm/cachectl.h> | 17 | #include <asm/cachectl.h> |
18 | #include <asm/fixmap.h> | 18 | #include <asm/fixmap.h> |
19 | 19 | ||
20 | #ifdef CONFIG_PAGE_SIZE_64KB | 20 | #if defined(CONFIG_PAGE_SIZE_64KB) && !defined(CONFIG_MIPS_VA_BITS_48) |
21 | #include <asm-generic/pgtable-nopmd.h> | 21 | #include <asm-generic/pgtable-nopmd.h> |
22 | #else | 22 | #else |
23 | #include <asm-generic/pgtable-nopud.h> | 23 | #include <asm-generic/pgtable-nopud.h> |
@@ -90,7 +90,11 @@ | |||
90 | #define PTE_ORDER 0 | 90 | #define PTE_ORDER 0 |
91 | #endif | 91 | #endif |
92 | #ifdef CONFIG_PAGE_SIZE_16KB | 92 | #ifdef CONFIG_PAGE_SIZE_16KB |
93 | #define PGD_ORDER 0 | 93 | #ifdef CONFIG_MIPS_VA_BITS_48 |
94 | #define PGD_ORDER 1 | ||
95 | #else | ||
96 | #define PGD_ORDER 0 | ||
97 | #endif | ||
94 | #define PUD_ORDER aieeee_attempt_to_allocate_pud | 98 | #define PUD_ORDER aieeee_attempt_to_allocate_pud |
95 | #define PMD_ORDER 0 | 99 | #define PMD_ORDER 0 |
96 | #define PTE_ORDER 0 | 100 | #define PTE_ORDER 0 |
@@ -104,7 +108,11 @@ | |||
104 | #ifdef CONFIG_PAGE_SIZE_64KB | 108 | #ifdef CONFIG_PAGE_SIZE_64KB |
105 | #define PGD_ORDER 0 | 109 | #define PGD_ORDER 0 |
106 | #define PUD_ORDER aieeee_attempt_to_allocate_pud | 110 | #define PUD_ORDER aieeee_attempt_to_allocate_pud |
111 | #ifdef CONFIG_MIPS_VA_BITS_48 | ||
112 | #define PMD_ORDER 0 | ||
113 | #else | ||
107 | #define PMD_ORDER aieeee_attempt_to_allocate_pmd | 114 | #define PMD_ORDER aieeee_attempt_to_allocate_pmd |
115 | #endif | ||
108 | #define PTE_ORDER 0 | 116 | #define PTE_ORDER 0 |
109 | #endif | 117 | #endif |
110 | 118 | ||
@@ -114,11 +122,7 @@ | |||
114 | #endif | 122 | #endif |
115 | #define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) | 123 | #define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) |
116 | 124 | ||
117 | #if PGDIR_SIZE >= TASK_SIZE64 | 125 | #define USER_PTRS_PER_PGD ((TASK_SIZE64 / PGDIR_SIZE)?(TASK_SIZE64 / PGDIR_SIZE):1) |
118 | #define USER_PTRS_PER_PGD (1) | ||
119 | #else | ||
120 | #define USER_PTRS_PER_PGD (TASK_SIZE64 / PGDIR_SIZE) | ||
121 | #endif | ||
122 | #define FIRST_USER_ADDRESS 0UL | 126 | #define FIRST_USER_ADDRESS 0UL |
123 | 127 | ||
124 | /* | 128 | /* |
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index 97b313882678..f88a48cd68b2 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h | |||
@@ -32,149 +32,132 @@ | |||
32 | * unpredictable things. The code (when it is written) to deal with | 32 | * unpredictable things. The code (when it is written) to deal with |
33 | * this problem will be in the update_mmu_cache() code for the r4k. | 33 | * this problem will be in the update_mmu_cache() code for the r4k. |
34 | */ | 34 | */ |
35 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 35 | #if defined(CONFIG_XPA) |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * The following bits are implemented by the TLB hardware | 38 | * Page table bit offsets used for 64 bit physical addressing on |
39 | * MIPS32r5 with XPA. | ||
39 | */ | 40 | */ |
40 | #define _PAGE_NO_EXEC_SHIFT 0 | 41 | enum pgtable_bits { |
41 | #define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT) | 42 | /* Used by TLB hardware (placed in EntryLo*) */ |
42 | #define _PAGE_NO_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1) | 43 | _PAGE_NO_EXEC_SHIFT, |
43 | #define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT) | 44 | _PAGE_NO_READ_SHIFT, |
44 | #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1) | 45 | _PAGE_GLOBAL_SHIFT, |
45 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | 46 | _PAGE_VALID_SHIFT, |
46 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) | 47 | _PAGE_DIRTY_SHIFT, |
47 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) | 48 | _CACHE_SHIFT, |
48 | #define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) | 49 | |
49 | #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) | 50 | /* Used only by software (masked out before writing EntryLo*) */ |
50 | #define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1) | 51 | _PAGE_PRESENT_SHIFT = 24, |
51 | #define _CACHE_MASK (7 << _CACHE_SHIFT) | 52 | _PAGE_WRITE_SHIFT, |
52 | 53 | _PAGE_ACCESSED_SHIFT, | |
53 | /* | 54 | _PAGE_MODIFIED_SHIFT, |
54 | * The following bits are implemented in software | 55 | }; |
55 | */ | ||
56 | #define _PAGE_PRESENT_SHIFT (24) | ||
57 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) | ||
58 | #define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) | ||
59 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) | ||
60 | #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) | ||
61 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | ||
62 | #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) | ||
63 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) | ||
64 | #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) | ||
65 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) | ||
66 | |||
67 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) | ||
68 | 56 | ||
69 | /* | 57 | /* |
70 | * Bits for extended EntryLo0/EntryLo1 registers | 58 | * Bits for extended EntryLo0/EntryLo1 registers |
71 | */ | 59 | */ |
72 | #define _PFNX_MASK 0xffffff | 60 | #define _PFNX_MASK 0xffffff |
73 | 61 | ||
74 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | 62 | #elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
75 | 63 | ||
76 | /* | 64 | /* |
77 | * The following bits are implemented in software | 65 | * Page table bit offsets used for 36 bit physical addressing on MIPS32, |
66 | * for example with Alchemy or Netlogic XLP/XLR. | ||
78 | */ | 67 | */ |
79 | #define _PAGE_PRESENT_SHIFT (0) | 68 | enum pgtable_bits { |
80 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) | 69 | /* Used by TLB hardware (placed in EntryLo*) */ |
81 | #define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) | 70 | _PAGE_GLOBAL_SHIFT, |
82 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) | 71 | _PAGE_VALID_SHIFT, |
83 | #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) | 72 | _PAGE_DIRTY_SHIFT, |
84 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | 73 | _CACHE_SHIFT, |
85 | #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) | 74 | |
86 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) | 75 | /* Used only by software (masked out before writing EntryLo*) */ |
87 | #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) | 76 | _PAGE_PRESENT_SHIFT = _CACHE_SHIFT + 3, |
88 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) | 77 | _PAGE_NO_READ_SHIFT, |
78 | _PAGE_WRITE_SHIFT, | ||
79 | _PAGE_ACCESSED_SHIFT, | ||
80 | _PAGE_MODIFIED_SHIFT, | ||
81 | }; | ||
89 | 82 | ||
90 | /* | 83 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) |
91 | * The following bits are implemented by the TLB hardware | ||
92 | */ | ||
93 | #define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 4) | ||
94 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | ||
95 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) | ||
96 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) | ||
97 | #define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) | ||
98 | #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) | ||
99 | #define _CACHE_UNCACHED_SHIFT (_PAGE_DIRTY_SHIFT + 1) | ||
100 | #define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT) | ||
101 | #define _CACHE_MASK _CACHE_UNCACHED | ||
102 | 84 | ||
103 | #define _PFN_SHIFT PAGE_SHIFT | 85 | /* Page table bits used for r3k systems */ |
86 | enum pgtable_bits { | ||
87 | /* Used only by software (writes to EntryLo ignored) */ | ||
88 | _PAGE_PRESENT_SHIFT, | ||
89 | _PAGE_NO_READ_SHIFT, | ||
90 | _PAGE_WRITE_SHIFT, | ||
91 | _PAGE_ACCESSED_SHIFT, | ||
92 | _PAGE_MODIFIED_SHIFT, | ||
93 | |||
94 | /* Used by TLB hardware (placed in EntryLo) */ | ||
95 | _PAGE_GLOBAL_SHIFT = 8, | ||
96 | _PAGE_VALID_SHIFT, | ||
97 | _PAGE_DIRTY_SHIFT, | ||
98 | _CACHE_UNCACHED_SHIFT, | ||
99 | }; | ||
104 | 100 | ||
105 | #else | 101 | #else |
106 | /* | ||
107 | * Below are the "Normal" R4K cases | ||
108 | */ | ||
109 | 102 | ||
110 | /* | 103 | /* Page table bits used for r4k systems */ |
111 | * The following bits are implemented in software | 104 | enum pgtable_bits { |
112 | */ | 105 | /* Used only by software (masked out before writing EntryLo*) */ |
113 | #define _PAGE_PRESENT_SHIFT 0 | 106 | _PAGE_PRESENT_SHIFT, |
107 | #if !defined(CONFIG_CPU_HAS_RIXI) | ||
108 | _PAGE_NO_READ_SHIFT, | ||
109 | #endif | ||
110 | _PAGE_WRITE_SHIFT, | ||
111 | _PAGE_ACCESSED_SHIFT, | ||
112 | _PAGE_MODIFIED_SHIFT, | ||
113 | #if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) | ||
114 | _PAGE_HUGE_SHIFT, | ||
115 | #endif | ||
116 | |||
117 | /* Used by TLB hardware (placed in EntryLo*) */ | ||
118 | #if defined(CONFIG_CPU_HAS_RIXI) | ||
119 | _PAGE_NO_EXEC_SHIFT, | ||
120 | _PAGE_NO_READ_SHIFT, | ||
121 | #endif | ||
122 | _PAGE_GLOBAL_SHIFT, | ||
123 | _PAGE_VALID_SHIFT, | ||
124 | _PAGE_DIRTY_SHIFT, | ||
125 | _CACHE_SHIFT, | ||
126 | }; | ||
127 | |||
128 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ | ||
129 | |||
130 | /* Used only by software */ | ||
114 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) | 131 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) |
115 | /* R2 or later cores check for RI/XI support to determine _PAGE_READ */ | ||
116 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) | ||
117 | #define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1) | ||
118 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | ||
119 | #else | ||
120 | #define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) | ||
121 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) | ||
122 | #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) | ||
123 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | 132 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) |
124 | #endif | ||
125 | #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) | ||
126 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) | 133 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) |
127 | #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) | ||
128 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) | 134 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) |
129 | |||
130 | #if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) | 135 | #if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) |
131 | /* Huge TLB page */ | 136 | # define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) |
132 | #define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1) | ||
133 | #define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) | ||
134 | #endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */ | ||
135 | |||
136 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) | ||
137 | /* XI - page cannot be executed */ | ||
138 | #ifdef _PAGE_HUGE_SHIFT | ||
139 | #define _PAGE_NO_EXEC_SHIFT (_PAGE_HUGE_SHIFT + 1) | ||
140 | #else | ||
141 | #define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1) | ||
142 | #endif | 137 | #endif |
143 | #define _PAGE_NO_EXEC (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0) | 138 | |
144 | 139 | /* Used by TLB hardware (placed in EntryLo*) */ | |
145 | /* RI - page cannot be read */ | 140 | #if defined(CONFIG_XPA) |
146 | #define _PAGE_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1) | 141 | # define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT) |
147 | #define _PAGE_READ (cpu_has_rixi ? 0 : (1 << _PAGE_READ_SHIFT)) | 142 | #elif defined(CONFIG_CPU_HAS_RIXI) |
148 | #define _PAGE_NO_READ_SHIFT _PAGE_READ_SHIFT | 143 | # define _PAGE_NO_EXEC (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0) |
149 | #define _PAGE_NO_READ (cpu_has_rixi ? (1 << _PAGE_READ_SHIFT) : 0) | ||
150 | #endif /* defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) */ | ||
151 | |||
152 | #if defined(_PAGE_NO_READ_SHIFT) | ||
153 | #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1) | ||
154 | #elif defined(_PAGE_HUGE_SHIFT) | ||
155 | #define _PAGE_GLOBAL_SHIFT (_PAGE_HUGE_SHIFT + 1) | ||
156 | #else | ||
157 | #define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 1) | ||
158 | #endif | 144 | #endif |
145 | #define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT) | ||
159 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | 146 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
160 | |||
161 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) | ||
162 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) | 147 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) |
163 | #define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) | ||
164 | #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) | 148 | #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) |
165 | #define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1) | 149 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) |
166 | #define _CACHE_MASK (7 << _CACHE_SHIFT) | 150 | # define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT) |
167 | 151 | # define _CACHE_MASK _CACHE_UNCACHED | |
168 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) | 152 | # define _PFN_SHIFT PAGE_SHIFT |
169 | 153 | #else | |
170 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ | 154 | # define _CACHE_MASK (7 << _CACHE_SHIFT) |
155 | # define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) | ||
156 | #endif | ||
171 | 157 | ||
172 | #ifndef _PAGE_NO_EXEC | 158 | #ifndef _PAGE_NO_EXEC |
173 | #define _PAGE_NO_EXEC 0 | 159 | #define _PAGE_NO_EXEC 0 |
174 | #endif | 160 | #endif |
175 | #ifndef _PAGE_NO_READ | ||
176 | #define _PAGE_NO_READ 0 | ||
177 | #endif | ||
178 | 161 | ||
179 | #define _PAGE_SILENT_READ _PAGE_VALID | 162 | #define _PAGE_SILENT_READ _PAGE_VALID |
180 | #define _PAGE_SILENT_WRITE _PAGE_DIRTY | 163 | #define _PAGE_SILENT_WRITE _PAGE_DIRTY |
@@ -191,14 +174,13 @@ | |||
191 | */ | 174 | */ |
192 | 175 | ||
193 | 176 | ||
194 | #ifndef __ASSEMBLY__ | ||
195 | /* | 177 | /* |
196 | * pte_to_entrylo converts a page table entry (PTE) into a Mips | 178 | * pte_to_entrylo converts a page table entry (PTE) into a Mips |
197 | * entrylo0/1 value. | 179 | * entrylo0/1 value. |
198 | */ | 180 | */ |
199 | static inline uint64_t pte_to_entrylo(unsigned long pte_val) | 181 | static inline uint64_t pte_to_entrylo(unsigned long pte_val) |
200 | { | 182 | { |
201 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) | 183 | #ifdef CONFIG_CPU_HAS_RIXI |
202 | if (cpu_has_rixi) { | 184 | if (cpu_has_rixi) { |
203 | int sa; | 185 | int sa; |
204 | #ifdef CONFIG_32BIT | 186 | #ifdef CONFIG_32BIT |
@@ -218,7 +200,6 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) | |||
218 | 200 | ||
219 | return pte_val >> _PAGE_GLOBAL_SHIFT; | 201 | return pte_val >> _PAGE_GLOBAL_SHIFT; |
220 | } | 202 | } |
221 | #endif | ||
222 | 203 | ||
223 | /* | 204 | /* |
224 | * Cache attributes | 205 | * Cache attributes |
@@ -274,7 +255,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) | |||
274 | #define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) | 255 | #define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) |
275 | #endif | 256 | #endif |
276 | 257 | ||
277 | #define __READABLE (_PAGE_SILENT_READ | _PAGE_READ | _PAGE_ACCESSED) | 258 | #define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED) |
278 | #define __WRITEABLE (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED) | 259 | #define __WRITEABLE (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED) |
279 | 260 | ||
280 | #define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED | \ | 261 | #define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED | \ |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 9a4fe0133ff1..e07a105cafc2 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
@@ -23,18 +23,19 @@ | |||
23 | struct mm_struct; | 23 | struct mm_struct; |
24 | struct vm_area_struct; | 24 | struct vm_area_struct; |
25 | 25 | ||
26 | #define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT) | 26 | #define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \ |
27 | #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | \ | 27 | _CACHE_CACHABLE_NONCOHERENT) |
28 | #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \ | ||
28 | _page_cachable_default) | 29 | _page_cachable_default) |
29 | #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_NO_EXEC | \ | 30 | #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \ |
30 | _page_cachable_default) | 31 | _page_cachable_default) |
31 | #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_READ | \ | 32 | #define PAGE_READONLY __pgprot(_PAGE_PRESENT | \ |
32 | _page_cachable_default) | 33 | _page_cachable_default) |
33 | #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ | 34 | #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ |
34 | _PAGE_GLOBAL | _page_cachable_default) | 35 | _PAGE_GLOBAL | _page_cachable_default) |
35 | #define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ | 36 | #define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ |
36 | _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT) | 37 | _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT) |
37 | #define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ | 38 | #define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \ |
38 | _page_cachable_default) | 39 | _page_cachable_default) |
39 | #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \ | 40 | #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \ |
40 | __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED) | 41 | __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED) |
@@ -127,10 +128,19 @@ do { \ | |||
127 | } \ | 128 | } \ |
128 | } while(0) | 129 | } while(0) |
129 | 130 | ||
131 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | ||
132 | pte_t *ptep, pte_t pteval); | ||
133 | |||
130 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 134 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
131 | 135 | ||
132 | #define pte_none(pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL)) | 136 | #ifdef CONFIG_XPA |
137 | # define pte_none(pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL)) | ||
138 | #else | ||
139 | # define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) | ||
140 | #endif | ||
141 | |||
133 | #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) | 142 | #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) |
143 | #define pte_no_exec(pte) ((pte).pte_low & _PAGE_NO_EXEC) | ||
134 | 144 | ||
135 | static inline void set_pte(pte_t *ptep, pte_t pte) | 145 | static inline void set_pte(pte_t *ptep, pte_t pte) |
136 | { | 146 | { |
@@ -138,17 +148,23 @@ static inline void set_pte(pte_t *ptep, pte_t pte) | |||
138 | smp_wmb(); | 148 | smp_wmb(); |
139 | ptep->pte_low = pte.pte_low; | 149 | ptep->pte_low = pte.pte_low; |
140 | 150 | ||
151 | #ifdef CONFIG_XPA | ||
141 | if (pte.pte_high & _PAGE_GLOBAL) { | 152 | if (pte.pte_high & _PAGE_GLOBAL) { |
153 | #else | ||
154 | if (pte.pte_low & _PAGE_GLOBAL) { | ||
155 | #endif | ||
142 | pte_t *buddy = ptep_buddy(ptep); | 156 | pte_t *buddy = ptep_buddy(ptep); |
143 | /* | 157 | /* |
144 | * Make sure the buddy is global too (if it's !none, | 158 | * Make sure the buddy is global too (if it's !none, |
145 | * it better already be global) | 159 | * it better already be global) |
146 | */ | 160 | */ |
147 | if (pte_none(*buddy)) | 161 | if (pte_none(*buddy)) { |
162 | if (!config_enabled(CONFIG_XPA)) | ||
163 | buddy->pte_low |= _PAGE_GLOBAL; | ||
148 | buddy->pte_high |= _PAGE_GLOBAL; | 164 | buddy->pte_high |= _PAGE_GLOBAL; |
165 | } | ||
149 | } | 166 | } |
150 | } | 167 | } |
151 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) | ||
152 | 168 | ||
153 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 169 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
154 | { | 170 | { |
@@ -156,8 +172,13 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt | |||
156 | 172 | ||
157 | htw_stop(); | 173 | htw_stop(); |
158 | /* Preserve global status for the pair */ | 174 | /* Preserve global status for the pair */ |
159 | if (ptep_buddy(ptep)->pte_high & _PAGE_GLOBAL) | 175 | if (config_enabled(CONFIG_XPA)) { |
160 | null.pte_high = _PAGE_GLOBAL; | 176 | if (ptep_buddy(ptep)->pte_high & _PAGE_GLOBAL) |
177 | null.pte_high = _PAGE_GLOBAL; | ||
178 | } else { | ||
179 | if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL) | ||
180 | null.pte_low = null.pte_high = _PAGE_GLOBAL; | ||
181 | } | ||
161 | 182 | ||
162 | set_pte_at(mm, addr, ptep, null); | 183 | set_pte_at(mm, addr, ptep, null); |
163 | htw_start(); | 184 | htw_start(); |
@@ -166,6 +187,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt | |||
166 | 187 | ||
167 | #define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL)) | 188 | #define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL)) |
168 | #define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) | 189 | #define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) |
190 | #define pte_no_exec(pte) (pte_val(pte) & _PAGE_NO_EXEC) | ||
169 | 191 | ||
170 | /* | 192 | /* |
171 | * Certain architectures need to do special things when pte's | 193 | * Certain architectures need to do special things when pte's |
@@ -187,30 +209,42 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) | |||
187 | * For SMP, multiple CPUs can race, so we need to do | 209 | * For SMP, multiple CPUs can race, so we need to do |
188 | * this atomically. | 210 | * this atomically. |
189 | */ | 211 | */ |
190 | #ifdef CONFIG_64BIT | ||
191 | #define LL_INSN "lld" | ||
192 | #define SC_INSN "scd" | ||
193 | #else /* CONFIG_32BIT */ | ||
194 | #define LL_INSN "ll" | ||
195 | #define SC_INSN "sc" | ||
196 | #endif | ||
197 | unsigned long page_global = _PAGE_GLOBAL; | 212 | unsigned long page_global = _PAGE_GLOBAL; |
198 | unsigned long tmp; | 213 | unsigned long tmp; |
199 | 214 | ||
200 | __asm__ __volatile__ ( | 215 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
201 | " .set push\n" | 216 | __asm__ __volatile__ ( |
202 | " .set noreorder\n" | 217 | " .set arch=r4000 \n" |
203 | "1: " LL_INSN " %[tmp], %[buddy]\n" | 218 | " .set push \n" |
204 | " bnez %[tmp], 2f\n" | 219 | " .set noreorder \n" |
205 | " or %[tmp], %[tmp], %[global]\n" | 220 | "1:" __LL "%[tmp], %[buddy] \n" |
206 | " " SC_INSN " %[tmp], %[buddy]\n" | 221 | " bnez %[tmp], 2f \n" |
207 | " beqz %[tmp], 1b\n" | 222 | " or %[tmp], %[tmp], %[global] \n" |
208 | " nop\n" | 223 | __SC "%[tmp], %[buddy] \n" |
209 | "2:\n" | 224 | " beqzl %[tmp], 1b \n" |
210 | " .set pop" | 225 | " nop \n" |
211 | : [buddy] "+m" (buddy->pte), | 226 | "2: \n" |
212 | [tmp] "=&r" (tmp) | 227 | " .set pop \n" |
228 | " .set mips0 \n" | ||
229 | : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) | ||
230 | : [global] "r" (page_global)); | ||
231 | } else if (kernel_uses_llsc) { | ||
232 | __asm__ __volatile__ ( | ||
233 | " .set "MIPS_ISA_ARCH_LEVEL" \n" | ||
234 | " .set push \n" | ||
235 | " .set noreorder \n" | ||
236 | "1:" __LL "%[tmp], %[buddy] \n" | ||
237 | " bnez %[tmp], 2f \n" | ||
238 | " or %[tmp], %[tmp], %[global] \n" | ||
239 | __SC "%[tmp], %[buddy] \n" | ||
240 | " beqz %[tmp], 1b \n" | ||
241 | " nop \n" | ||
242 | "2: \n" | ||
243 | " .set pop \n" | ||
244 | " .set mips0 \n" | ||
245 | : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) | ||
213 | : [global] "r" (page_global)); | 246 | : [global] "r" (page_global)); |
247 | } | ||
214 | #else /* !CONFIG_SMP */ | 248 | #else /* !CONFIG_SMP */ |
215 | if (pte_none(*buddy)) | 249 | if (pte_none(*buddy)) |
216 | pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL; | 250 | pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL; |
@@ -218,7 +252,6 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) | |||
218 | } | 252 | } |
219 | #endif | 253 | #endif |
220 | } | 254 | } |
221 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) | ||
222 | 255 | ||
223 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 256 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
224 | { | 257 | { |
@@ -234,6 +267,22 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt | |||
234 | } | 267 | } |
235 | #endif | 268 | #endif |
236 | 269 | ||
270 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | ||
271 | pte_t *ptep, pte_t pteval) | ||
272 | { | ||
273 | extern void __update_cache(unsigned long address, pte_t pte); | ||
274 | |||
275 | if (!pte_present(pteval)) | ||
276 | goto cache_sync_done; | ||
277 | |||
278 | if (pte_present(*ptep) && (pte_pfn(*ptep) == pte_pfn(pteval))) | ||
279 | goto cache_sync_done; | ||
280 | |||
281 | __update_cache(addr, pteval); | ||
282 | cache_sync_done: | ||
283 | set_pte(ptep, pteval); | ||
284 | } | ||
285 | |||
237 | /* | 286 | /* |
238 | * (pmds are folded into puds so this doesn't get actually called, | 287 | * (pmds are folded into puds so this doesn't get actually called, |
239 | * but the define is needed for a generic inline function.) | 288 | * but the define is needed for a generic inline function.) |
@@ -270,6 +319,8 @@ static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } | |||
270 | static inline pte_t pte_wrprotect(pte_t pte) | 319 | static inline pte_t pte_wrprotect(pte_t pte) |
271 | { | 320 | { |
272 | pte.pte_low &= ~_PAGE_WRITE; | 321 | pte.pte_low &= ~_PAGE_WRITE; |
322 | if (!config_enabled(CONFIG_XPA)) | ||
323 | pte.pte_low &= ~_PAGE_SILENT_WRITE; | ||
273 | pte.pte_high &= ~_PAGE_SILENT_WRITE; | 324 | pte.pte_high &= ~_PAGE_SILENT_WRITE; |
274 | return pte; | 325 | return pte; |
275 | } | 326 | } |
@@ -277,6 +328,8 @@ static inline pte_t pte_wrprotect(pte_t pte) | |||
277 | static inline pte_t pte_mkclean(pte_t pte) | 328 | static inline pte_t pte_mkclean(pte_t pte) |
278 | { | 329 | { |
279 | pte.pte_low &= ~_PAGE_MODIFIED; | 330 | pte.pte_low &= ~_PAGE_MODIFIED; |
331 | if (!config_enabled(CONFIG_XPA)) | ||
332 | pte.pte_low &= ~_PAGE_SILENT_WRITE; | ||
280 | pte.pte_high &= ~_PAGE_SILENT_WRITE; | 333 | pte.pte_high &= ~_PAGE_SILENT_WRITE; |
281 | return pte; | 334 | return pte; |
282 | } | 335 | } |
@@ -284,6 +337,8 @@ static inline pte_t pte_mkclean(pte_t pte) | |||
284 | static inline pte_t pte_mkold(pte_t pte) | 337 | static inline pte_t pte_mkold(pte_t pte) |
285 | { | 338 | { |
286 | pte.pte_low &= ~_PAGE_ACCESSED; | 339 | pte.pte_low &= ~_PAGE_ACCESSED; |
340 | if (!config_enabled(CONFIG_XPA)) | ||
341 | pte.pte_low &= ~_PAGE_SILENT_READ; | ||
287 | pte.pte_high &= ~_PAGE_SILENT_READ; | 342 | pte.pte_high &= ~_PAGE_SILENT_READ; |
288 | return pte; | 343 | return pte; |
289 | } | 344 | } |
@@ -291,24 +346,33 @@ static inline pte_t pte_mkold(pte_t pte) | |||
291 | static inline pte_t pte_mkwrite(pte_t pte) | 346 | static inline pte_t pte_mkwrite(pte_t pte) |
292 | { | 347 | { |
293 | pte.pte_low |= _PAGE_WRITE; | 348 | pte.pte_low |= _PAGE_WRITE; |
294 | if (pte.pte_low & _PAGE_MODIFIED) | 349 | if (pte.pte_low & _PAGE_MODIFIED) { |
350 | if (!config_enabled(CONFIG_XPA)) | ||
351 | pte.pte_low |= _PAGE_SILENT_WRITE; | ||
295 | pte.pte_high |= _PAGE_SILENT_WRITE; | 352 | pte.pte_high |= _PAGE_SILENT_WRITE; |
353 | } | ||
296 | return pte; | 354 | return pte; |
297 | } | 355 | } |
298 | 356 | ||
299 | static inline pte_t pte_mkdirty(pte_t pte) | 357 | static inline pte_t pte_mkdirty(pte_t pte) |
300 | { | 358 | { |
301 | pte.pte_low |= _PAGE_MODIFIED; | 359 | pte.pte_low |= _PAGE_MODIFIED; |
302 | if (pte.pte_low & _PAGE_WRITE) | 360 | if (pte.pte_low & _PAGE_WRITE) { |
361 | if (!config_enabled(CONFIG_XPA)) | ||
362 | pte.pte_low |= _PAGE_SILENT_WRITE; | ||
303 | pte.pte_high |= _PAGE_SILENT_WRITE; | 363 | pte.pte_high |= _PAGE_SILENT_WRITE; |
364 | } | ||
304 | return pte; | 365 | return pte; |
305 | } | 366 | } |
306 | 367 | ||
307 | static inline pte_t pte_mkyoung(pte_t pte) | 368 | static inline pte_t pte_mkyoung(pte_t pte) |
308 | { | 369 | { |
309 | pte.pte_low |= _PAGE_ACCESSED; | 370 | pte.pte_low |= _PAGE_ACCESSED; |
310 | if (pte.pte_low & _PAGE_READ) | 371 | if (!(pte.pte_low & _PAGE_NO_READ)) { |
372 | if (!config_enabled(CONFIG_XPA)) | ||
373 | pte.pte_low |= _PAGE_SILENT_READ; | ||
311 | pte.pte_high |= _PAGE_SILENT_READ; | 374 | pte.pte_high |= _PAGE_SILENT_READ; |
375 | } | ||
312 | return pte; | 376 | return pte; |
313 | } | 377 | } |
314 | #else | 378 | #else |
@@ -353,13 +417,8 @@ static inline pte_t pte_mkdirty(pte_t pte) | |||
353 | static inline pte_t pte_mkyoung(pte_t pte) | 417 | static inline pte_t pte_mkyoung(pte_t pte) |
354 | { | 418 | { |
355 | pte_val(pte) |= _PAGE_ACCESSED; | 419 | pte_val(pte) |= _PAGE_ACCESSED; |
356 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) | ||
357 | if (!(pte_val(pte) & _PAGE_NO_READ)) | 420 | if (!(pte_val(pte) & _PAGE_NO_READ)) |
358 | pte_val(pte) |= _PAGE_SILENT_READ; | 421 | pte_val(pte) |= _PAGE_SILENT_READ; |
359 | else | ||
360 | #endif | ||
361 | if (pte_val(pte) & _PAGE_READ) | ||
362 | pte_val(pte) |= _PAGE_SILENT_READ; | ||
363 | return pte; | 422 | return pte; |
364 | } | 423 | } |
365 | 424 | ||
@@ -411,7 +470,7 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) | |||
411 | */ | 470 | */ |
412 | #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) | 471 | #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) |
413 | 472 | ||
414 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 473 | #if defined(CONFIG_XPA) |
415 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 474 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
416 | { | 475 | { |
417 | pte.pte_low &= (_PAGE_MODIFIED | _PAGE_ACCESSED | _PFNX_MASK); | 476 | pte.pte_low &= (_PAGE_MODIFIED | _PAGE_ACCESSED | _PFNX_MASK); |
@@ -420,6 +479,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
420 | pte.pte_high |= pgprot_val(newprot) & ~_PFN_MASK; | 479 | pte.pte_high |= pgprot_val(newprot) & ~_PFN_MASK; |
421 | return pte; | 480 | return pte; |
422 | } | 481 | } |
482 | #elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | ||
483 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | ||
484 | { | ||
485 | pte.pte_low &= _PAGE_CHG_MASK; | ||
486 | pte.pte_high &= (_PFN_MASK | _CACHE_MASK); | ||
487 | pte.pte_low |= pgprot_val(newprot); | ||
488 | pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK); | ||
489 | return pte; | ||
490 | } | ||
423 | #else | 491 | #else |
424 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 492 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
425 | { | 493 | { |
@@ -430,15 +498,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
430 | 498 | ||
431 | extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, | 499 | extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, |
432 | pte_t pte); | 500 | pte_t pte); |
433 | extern void __update_cache(struct vm_area_struct *vma, unsigned long address, | ||
434 | pte_t pte); | ||
435 | 501 | ||
436 | static inline void update_mmu_cache(struct vm_area_struct *vma, | 502 | static inline void update_mmu_cache(struct vm_area_struct *vma, |
437 | unsigned long address, pte_t *ptep) | 503 | unsigned long address, pte_t *ptep) |
438 | { | 504 | { |
439 | pte_t pte = *ptep; | 505 | pte_t pte = *ptep; |
440 | __update_tlb(vma, address, pte); | 506 | __update_tlb(vma, address, pte); |
441 | __update_cache(vma, address, pte); | ||
442 | } | 507 | } |
443 | 508 | ||
444 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, | 509 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, |
@@ -542,13 +607,8 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) | |||
542 | { | 607 | { |
543 | pmd_val(pmd) |= _PAGE_ACCESSED; | 608 | pmd_val(pmd) |= _PAGE_ACCESSED; |
544 | 609 | ||
545 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) | ||
546 | if (!(pmd_val(pmd) & _PAGE_NO_READ)) | 610 | if (!(pmd_val(pmd) & _PAGE_NO_READ)) |
547 | pmd_val(pmd) |= _PAGE_SILENT_READ; | 611 | pmd_val(pmd) |= _PAGE_SILENT_READ; |
548 | else | ||
549 | #endif | ||
550 | if (pmd_val(pmd) & _PAGE_READ) | ||
551 | pmd_val(pmd) |= _PAGE_SILENT_READ; | ||
552 | 612 | ||
553 | return pmd; | 613 | return pmd; |
554 | } | 614 | } |
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 041153f5cf93..7e78b6208d7d 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h | |||
@@ -63,7 +63,11 @@ extern unsigned int vced_count, vcei_count; | |||
63 | * 8192EB ... | 63 | * 8192EB ... |
64 | */ | 64 | */ |
65 | #define TASK_SIZE32 0x7fff8000UL | 65 | #define TASK_SIZE32 0x7fff8000UL |
66 | #define TASK_SIZE64 0x10000000000UL | 66 | #ifdef CONFIG_MIPS_VA_BITS_48 |
67 | #define TASK_SIZE64 (0x1UL << ((cpu_data[0].vmbits>48)?48:cpu_data[0].vmbits)) | ||
68 | #else | ||
69 | #define TASK_SIZE64 0x10000000000UL | ||
70 | #endif | ||
67 | #define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64) | 71 | #define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64) |
68 | #define STACK_TOP_MAX TASK_SIZE64 | 72 | #define STACK_TOP_MAX TASK_SIZE64 |
69 | 73 | ||
@@ -355,6 +359,10 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); | |||
355 | */ | 359 | */ |
356 | extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); | 360 | extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); |
357 | 361 | ||
362 | static inline void flush_thread(void) | ||
363 | { | ||
364 | } | ||
365 | |||
358 | unsigned long get_wchan(struct task_struct *p); | 366 | unsigned long get_wchan(struct task_struct *p); |
359 | 367 | ||
360 | #define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \ | 368 | #define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \ |
diff --git a/arch/mips/include/asm/seccomp.h b/arch/mips/include/asm/seccomp.h index 1d8a2e2c75c1..684fb3a12ed3 100644 --- a/arch/mips/include/asm/seccomp.h +++ b/arch/mips/include/asm/seccomp.h | |||
@@ -2,27 +2,32 @@ | |||
2 | 2 | ||
3 | #include <linux/unistd.h> | 3 | #include <linux/unistd.h> |
4 | 4 | ||
5 | /* | 5 | #ifdef CONFIG_COMPAT |
6 | * Kludge alert: | 6 | static inline const int *get_compat_mode1_syscalls(void) |
7 | * | 7 | { |
8 | * The generic seccomp code currently allows only a single compat ABI. Until | 8 | static const int syscalls_O32[] = { |
9 | * this is fixed we priorize O32 as the compat ABI over N32. | 9 | __NR_O32_Linux + 3, __NR_O32_Linux + 4, |
10 | */ | 10 | __NR_O32_Linux + 1, __NR_O32_Linux + 193, |
11 | #ifdef CONFIG_MIPS32_O32 | 11 | 0, /* null terminated */ |
12 | 12 | }; | |
13 | #define __NR_seccomp_read_32 4003 | 13 | static const int syscalls_N32[] = { |
14 | #define __NR_seccomp_write_32 4004 | 14 | __NR_N32_Linux + 0, __NR_N32_Linux + 1, |
15 | #define __NR_seccomp_exit_32 4001 | 15 | __NR_N32_Linux + 58, __NR_N32_Linux + 211, |
16 | #define __NR_seccomp_sigreturn_32 4193 /* rt_sigreturn */ | 16 | 0, /* null terminated */ |
17 | 17 | }; | |
18 | #elif defined(CONFIG_MIPS32_N32) | 18 | |
19 | 19 | if (config_enabled(CONFIG_MIPS32_O32) && test_thread_flag(TIF_32BIT_REGS)) | |
20 | #define __NR_seccomp_read_32 6000 | 20 | return syscalls_O32; |
21 | #define __NR_seccomp_write_32 6001 | 21 | |
22 | #define __NR_seccomp_exit_32 6058 | 22 | if (config_enabled(CONFIG_MIPS32_N32)) |
23 | #define __NR_seccomp_sigreturn_32 6211 /* rt_sigreturn */ | 23 | return syscalls_N32; |
24 | 24 | ||
25 | #endif /* CONFIG_MIPS32_O32 */ | 25 | BUG(); |
26 | } | ||
27 | |||
28 | #define get_compat_mode1_syscalls get_compat_mode1_syscalls | ||
29 | |||
30 | #endif /* CONFIG_COMPAT */ | ||
26 | 31 | ||
27 | #include <asm-generic/seccomp.h> | 32 | #include <asm-generic/seccomp.h> |
28 | 33 | ||
diff --git a/arch/mips/include/asm/sibyte/bcm1480_regs.h b/arch/mips/include/asm/sibyte/bcm1480_regs.h index ec0dacf6f0cb..32a84837b8fa 100644 --- a/arch/mips/include/asm/sibyte/bcm1480_regs.h +++ b/arch/mips/include/asm/sibyte/bcm1480_regs.h | |||
@@ -415,8 +415,8 @@ | |||
415 | (cpu)*BCM1480_IMR_ALIAS_MAILBOX_SPACING) | 415 | (cpu)*BCM1480_IMR_ALIAS_MAILBOX_SPACING) |
416 | #define A_BCM1480_IMR_ALIAS_MAILBOX_REGISTER(cpu, reg) (A_BCM1480_IMR_ALIAS_MAILBOX(cpu)+(reg)) | 416 | #define A_BCM1480_IMR_ALIAS_MAILBOX_REGISTER(cpu, reg) (A_BCM1480_IMR_ALIAS_MAILBOX(cpu)+(reg)) |
417 | 417 | ||
418 | #define R_BCM1480_IMR_ALIAS_MAILBOX_0 0x0000 /* 0x0x0 */ | 418 | #define R_BCM1480_IMR_ALIAS_MAILBOX_0 0x0000 |
419 | #define R_BCM1480_IMR_ALIAS_MAILBOX_0_SET 0x0008 /* 0x0x8 */ | 419 | #define R_BCM1480_IMR_ALIAS_MAILBOX_0_SET 0x0008 |
420 | 420 | ||
421 | /* | 421 | /* |
422 | * these macros work together to build the address of a mailbox | 422 | * these macros work together to build the address of a mailbox |
diff --git a/arch/mips/include/asm/signal.h b/arch/mips/include/asm/signal.h index 003e273eff4c..2292373ff11a 100644 --- a/arch/mips/include/asm/signal.h +++ b/arch/mips/include/asm/signal.h | |||
@@ -11,11 +11,17 @@ | |||
11 | 11 | ||
12 | #include <uapi/asm/signal.h> | 12 | #include <uapi/asm/signal.h> |
13 | 13 | ||
14 | #ifdef CONFIG_MIPS32_COMPAT | ||
15 | extern struct mips_abi mips_abi_32; | ||
14 | 16 | ||
15 | #ifdef CONFIG_TRAD_SIGNALS | 17 | #define sig_uses_siginfo(ka, abi) \ |
16 | #define sig_uses_siginfo(ka) ((ka)->sa.sa_flags & SA_SIGINFO) | 18 | ((abi != &mips_abi_32) ? 1 : \ |
19 | ((ka)->sa.sa_flags & SA_SIGINFO)) | ||
17 | #else | 20 | #else |
18 | #define sig_uses_siginfo(ka) (1) | 21 | #define sig_uses_siginfo(ka, abi) \ |
22 | (config_enabled(CONFIG_64BIT) ? 1 : \ | ||
23 | (config_enabled(CONFIG_TRAD_SIGNALS) ? \ | ||
24 | ((ka)->sa.sa_flags & SA_SIGINFO) : 1) ) | ||
19 | #endif | 25 | #endif |
20 | 26 | ||
21 | #include <asm/sigcontext.h> | 27 | #include <asm/sigcontext.h> |
diff --git a/arch/mips/include/asm/smp-cps.h b/arch/mips/include/asm/smp-cps.h index 326c16ebd589..2ae1f61a4a95 100644 --- a/arch/mips/include/asm/smp-cps.h +++ b/arch/mips/include/asm/smp-cps.h | |||
@@ -29,7 +29,7 @@ extern struct core_boot_config *mips_cps_core_bootcfg; | |||
29 | extern void mips_cps_core_entry(void); | 29 | extern void mips_cps_core_entry(void); |
30 | extern void mips_cps_core_init(void); | 30 | extern void mips_cps_core_init(void); |
31 | 31 | ||
32 | extern struct vpe_boot_config *mips_cps_boot_vpes(void); | 32 | extern void mips_cps_boot_vpes(struct core_boot_config *cfg, unsigned vpe); |
33 | 33 | ||
34 | extern void mips_cps_pm_save(void); | 34 | extern void mips_cps_pm_save(void); |
35 | extern void mips_cps_pm_restore(void); | 35 | extern void mips_cps_pm_restore(void); |
diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index 28b5d84a5022..ebb5c0f2f90d 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h | |||
@@ -105,7 +105,7 @@ do { \ | |||
105 | __clear_software_ll_bit(); \ | 105 | __clear_software_ll_bit(); \ |
106 | if (cpu_has_userlocal) \ | 106 | if (cpu_has_userlocal) \ |
107 | write_c0_userlocal(task_thread_info(next)->tp_value); \ | 107 | write_c0_userlocal(task_thread_info(next)->tp_value); \ |
108 | __restore_watch(); \ | 108 | __restore_watch(next); \ |
109 | (last) = resume(prev, next, task_thread_info(next)); \ | 109 | (last) = resume(prev, next, task_thread_info(next)); \ |
110 | } while (0) | 110 | } while (0) |
111 | 111 | ||
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index fc1cdd25fcda..b6ecfeee4dbe 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h | |||
@@ -171,7 +171,8 @@ Ip_u2u1(_wsbh); | |||
171 | Ip_u3u1u2(_xor); | 171 | Ip_u3u1u2(_xor); |
172 | Ip_u2u1u3(_xori); | 172 | Ip_u2u1u3(_xori); |
173 | Ip_u2u1(_yield); | 173 | Ip_u2u1(_yield); |
174 | 174 | Ip_u1u2(_ldpte); | |
175 | Ip_u2u1u3(_lddir); | ||
175 | 176 | ||
176 | /* Handle labels. */ | 177 | /* Handle labels. */ |
177 | struct uasm_label { | 178 | struct uasm_label { |
diff --git a/arch/mips/include/asm/watch.h b/arch/mips/include/asm/watch.h index 20126ec79359..6ffe3eadf105 100644 --- a/arch/mips/include/asm/watch.h +++ b/arch/mips/include/asm/watch.h | |||
@@ -12,21 +12,21 @@ | |||
12 | 12 | ||
13 | #include <asm/mipsregs.h> | 13 | #include <asm/mipsregs.h> |
14 | 14 | ||
15 | void mips_install_watch_registers(void); | 15 | void mips_install_watch_registers(struct task_struct *t); |
16 | void mips_read_watch_registers(void); | 16 | void mips_read_watch_registers(void); |
17 | void mips_clear_watch_registers(void); | 17 | void mips_clear_watch_registers(void); |
18 | void mips_probe_watch_registers(struct cpuinfo_mips *c); | 18 | void mips_probe_watch_registers(struct cpuinfo_mips *c); |
19 | 19 | ||
20 | #ifdef CONFIG_HARDWARE_WATCHPOINTS | 20 | #ifdef CONFIG_HARDWARE_WATCHPOINTS |
21 | #define __restore_watch() do { \ | 21 | #define __restore_watch(task) do { \ |
22 | if (unlikely(test_bit(TIF_LOAD_WATCH, \ | 22 | if (unlikely(test_bit(TIF_LOAD_WATCH, \ |
23 | ¤t_thread_info()->flags))) { \ | 23 | &task_thread_info(task)->flags))) { \ |
24 | mips_install_watch_registers(); \ | 24 | mips_install_watch_registers(task); \ |
25 | } \ | 25 | } \ |
26 | } while (0) | 26 | } while (0) |
27 | 27 | ||
28 | #else | 28 | #else |
29 | #define __restore_watch() do {} while (0) | 29 | #define __restore_watch(task) do {} while (0) |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #endif /* _ASM_WATCH_H */ | 32 | #endif /* _ASM_WATCH_H */ |
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index ddea53e3a9bb..8051f9aa1379 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h | |||
@@ -167,6 +167,7 @@ enum cop1_sdw_func { | |||
167 | fceill_op = 0x0a, ffloorl_op = 0x0b, | 167 | fceill_op = 0x0a, ffloorl_op = 0x0b, |
168 | fround_op = 0x0c, ftrunc_op = 0x0d, | 168 | fround_op = 0x0c, ftrunc_op = 0x0d, |
169 | fceil_op = 0x0e, ffloor_op = 0x0f, | 169 | fceil_op = 0x0e, ffloor_op = 0x0f, |
170 | fsel_op = 0x10, | ||
170 | fmovc_op = 0x11, fmovz_op = 0x12, | 171 | fmovc_op = 0x11, fmovz_op = 0x12, |
171 | fmovn_op = 0x13, fseleqz_op = 0x14, | 172 | fmovn_op = 0x13, fseleqz_op = 0x14, |
172 | frecip_op = 0x15, frsqrt_op = 0x16, | 173 | frecip_op = 0x15, frsqrt_op = 0x16, |
@@ -204,6 +205,16 @@ enum mad_func { | |||
204 | }; | 205 | }; |
205 | 206 | ||
206 | /* | 207 | /* |
208 | * func field for page table walker (Loongson-3). | ||
209 | */ | ||
210 | enum ptw_func { | ||
211 | lwdir_op = 0x00, | ||
212 | lwpte_op = 0x01, | ||
213 | lddir_op = 0x02, | ||
214 | ldpte_op = 0x03, | ||
215 | }; | ||
216 | |||
217 | /* | ||
207 | * func field for special3 lx opcodes (Cavium Octeon). | 218 | * func field for special3 lx opcodes (Cavium Octeon). |
208 | */ | 219 | */ |
209 | enum lx_func { | 220 | enum lx_func { |
diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h index cc49dc240d67..8069cf766603 100644 --- a/arch/mips/include/uapi/asm/siginfo.h +++ b/arch/mips/include/uapi/asm/siginfo.h | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #define __ARCH_SIGSYS | 29 | #define __ARCH_SIGSYS |
30 | 30 | ||
31 | #include <uapi/asm-generic/siginfo.h> | 31 | #include <asm-generic/siginfo.h> |
32 | 32 | ||
33 | /* We can't use generic siginfo_t, because our si_code and si_errno are swapped */ | 33 | /* We can't use generic siginfo_t, because our si_code and si_errno are swapped */ |
34 | typedef struct siginfo { | 34 | typedef struct siginfo { |
@@ -42,13 +42,13 @@ typedef struct siginfo { | |||
42 | 42 | ||
43 | /* kill() */ | 43 | /* kill() */ |
44 | struct { | 44 | struct { |
45 | pid_t _pid; /* sender's pid */ | 45 | __kernel_pid_t _pid; /* sender's pid */ |
46 | __ARCH_SI_UID_T _uid; /* sender's uid */ | 46 | __ARCH_SI_UID_T _uid; /* sender's uid */ |
47 | } _kill; | 47 | } _kill; |
48 | 48 | ||
49 | /* POSIX.1b timers */ | 49 | /* POSIX.1b timers */ |
50 | struct { | 50 | struct { |
51 | timer_t _tid; /* timer id */ | 51 | __kernel_timer_t _tid; /* timer id */ |
52 | int _overrun; /* overrun count */ | 52 | int _overrun; /* overrun count */ |
53 | char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; | 53 | char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; |
54 | sigval_t _sigval; /* same as below */ | 54 | sigval_t _sigval; /* same as below */ |
@@ -57,26 +57,26 @@ typedef struct siginfo { | |||
57 | 57 | ||
58 | /* POSIX.1b signals */ | 58 | /* POSIX.1b signals */ |
59 | struct { | 59 | struct { |
60 | pid_t _pid; /* sender's pid */ | 60 | __kernel_pid_t _pid; /* sender's pid */ |
61 | __ARCH_SI_UID_T _uid; /* sender's uid */ | 61 | __ARCH_SI_UID_T _uid; /* sender's uid */ |
62 | sigval_t _sigval; | 62 | sigval_t _sigval; |
63 | } _rt; | 63 | } _rt; |
64 | 64 | ||
65 | /* SIGCHLD */ | 65 | /* SIGCHLD */ |
66 | struct { | 66 | struct { |
67 | pid_t _pid; /* which child */ | 67 | __kernel_pid_t _pid; /* which child */ |
68 | __ARCH_SI_UID_T _uid; /* sender's uid */ | 68 | __ARCH_SI_UID_T _uid; /* sender's uid */ |
69 | int _status; /* exit code */ | 69 | int _status; /* exit code */ |
70 | clock_t _utime; | 70 | __kernel_clock_t _utime; |
71 | clock_t _stime; | 71 | __kernel_clock_t _stime; |
72 | } _sigchld; | 72 | } _sigchld; |
73 | 73 | ||
74 | /* IRIX SIGCHLD */ | 74 | /* IRIX SIGCHLD */ |
75 | struct { | 75 | struct { |
76 | pid_t _pid; /* which child */ | 76 | __kernel_pid_t _pid; /* which child */ |
77 | clock_t _utime; | 77 | __kernel_clock_t _utime; |
78 | int _status; /* exit code */ | 78 | int _status; /* exit code */ |
79 | clock_t _stime; | 79 | __kernel_clock_t _stime; |
80 | } _irix_sigchld; | 80 | } _irix_sigchld; |
81 | 81 | ||
82 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | 82 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ |
@@ -123,6 +123,4 @@ typedef struct siginfo { | |||
123 | #define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */ | 123 | #define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */ |
124 | #define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */ | 124 | #define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */ |
125 | 125 | ||
126 | #include <asm-generic/siginfo.h> | ||
127 | |||
128 | #endif /* _UAPI_ASM_SIGINFO_H */ | 126 | #endif /* _UAPI_ASM_SIGINFO_H */ |
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 934b15b5b575..4e3f9b7a02e4 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
@@ -39,8 +39,6 @@ | |||
39 | 39 | ||
40 | #include "clock.h" | 40 | #include "clock.h" |
41 | 41 | ||
42 | static bool is_avt2; | ||
43 | |||
44 | /* GPIOs */ | 42 | /* GPIOs */ |
45 | #define QI_LB60_GPIO_SD_CD JZ_GPIO_PORTD(0) | 43 | #define QI_LB60_GPIO_SD_CD JZ_GPIO_PORTD(0) |
46 | #define QI_LB60_GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(2) | 44 | #define QI_LB60_GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(2) |
@@ -367,43 +365,12 @@ static struct jz4740_mmc_platform_data qi_lb60_mmc_pdata = { | |||
367 | .power_active_low = 1, | 365 | .power_active_low = 1, |
368 | }; | 366 | }; |
369 | 367 | ||
370 | /* OHCI */ | 368 | /* beeper */ |
371 | static struct regulator_consumer_supply avt2_usb_regulator_consumer = | ||
372 | REGULATOR_SUPPLY("vbus", "jz4740-ohci"); | ||
373 | |||
374 | static struct regulator_init_data avt2_usb_regulator_init_data = { | ||
375 | .num_consumer_supplies = 1, | ||
376 | .consumer_supplies = &avt2_usb_regulator_consumer, | ||
377 | .constraints = { | ||
378 | .name = "USB power", | ||
379 | .min_uV = 5000000, | ||
380 | .max_uV = 5000000, | ||
381 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
382 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
383 | }, | ||
384 | }; | ||
385 | |||
386 | static struct fixed_voltage_config avt2_usb_regulator_data = { | ||
387 | .supply_name = "USB power", | ||
388 | .microvolts = 5000000, | ||
389 | .gpio = JZ_GPIO_PORTB(17), | ||
390 | .init_data = &avt2_usb_regulator_init_data, | ||
391 | }; | ||
392 | |||
393 | static struct platform_device avt2_usb_regulator_device = { | ||
394 | .name = "reg-fixed-voltage", | ||
395 | .id = -1, | ||
396 | .dev = { | ||
397 | .platform_data = &avt2_usb_regulator_data, | ||
398 | } | ||
399 | }; | ||
400 | |||
401 | static struct pwm_lookup qi_lb60_pwm_lookup[] = { | 369 | static struct pwm_lookup qi_lb60_pwm_lookup[] = { |
402 | PWM_LOOKUP("jz4740-pwm", 4, "pwm-beeper", NULL, 0, | 370 | PWM_LOOKUP("jz4740-pwm", 4, "pwm-beeper", NULL, 0, |
403 | PWM_POLARITY_NORMAL), | 371 | PWM_POLARITY_NORMAL), |
404 | }; | 372 | }; |
405 | 373 | ||
406 | /* beeper */ | ||
407 | static struct platform_device qi_lb60_pwm_beeper = { | 374 | static struct platform_device qi_lb60_pwm_beeper = { |
408 | .name = "pwm-beeper", | 375 | .name = "pwm-beeper", |
409 | .id = -1, | 376 | .id = -1, |
@@ -487,11 +454,6 @@ static int __init qi_lb60_init_platform_devices(void) | |||
487 | spi_register_board_info(qi_lb60_spi_board_info, | 454 | spi_register_board_info(qi_lb60_spi_board_info, |
488 | ARRAY_SIZE(qi_lb60_spi_board_info)); | 455 | ARRAY_SIZE(qi_lb60_spi_board_info)); |
489 | 456 | ||
490 | if (is_avt2) { | ||
491 | platform_device_register(&avt2_usb_regulator_device); | ||
492 | platform_device_register(&jz4740_usb_ohci_device); | ||
493 | } | ||
494 | |||
495 | pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup)); | 457 | pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup)); |
496 | 458 | ||
497 | return platform_add_devices(jz_platform_devices, | 459 | return platform_add_devices(jz_platform_devices, |
@@ -499,19 +461,9 @@ static int __init qi_lb60_init_platform_devices(void) | |||
499 | 461 | ||
500 | } | 462 | } |
501 | 463 | ||
502 | static __init int board_avt2(char *str) | ||
503 | { | ||
504 | qi_lb60_mmc_pdata.card_detect_active_low = 1; | ||
505 | is_avt2 = true; | ||
506 | |||
507 | return 1; | ||
508 | } | ||
509 | __setup("avt2", board_avt2); | ||
510 | |||
511 | static int __init qi_lb60_board_setup(void) | 464 | static int __init qi_lb60_board_setup(void) |
512 | { | 465 | { |
513 | printk(KERN_INFO "Qi Hardware JZ4740 QI %s setup\n", | 466 | printk(KERN_INFO "Qi Hardware JZ4740 QI LB60 setup\n"); |
514 | is_avt2 ? "AVT2" : "LB60"); | ||
515 | 467 | ||
516 | board_gpio_setup(); | 468 | board_gpio_setup(); |
517 | 469 | ||
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index e8a463b9b663..2f1dab35c061 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c | |||
@@ -32,31 +32,6 @@ | |||
32 | 32 | ||
33 | #include "clock.h" | 33 | #include "clock.h" |
34 | 34 | ||
35 | /* OHCI controller */ | ||
36 | static struct resource jz4740_usb_ohci_resources[] = { | ||
37 | { | ||
38 | .start = JZ4740_UHC_BASE_ADDR, | ||
39 | .end = JZ4740_UHC_BASE_ADDR + 0x1000 - 1, | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }, | ||
42 | { | ||
43 | .start = JZ4740_IRQ_UHC, | ||
44 | .end = JZ4740_IRQ_UHC, | ||
45 | .flags = IORESOURCE_IRQ, | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | struct platform_device jz4740_usb_ohci_device = { | ||
50 | .name = "jz4740-ohci", | ||
51 | .id = -1, | ||
52 | .dev = { | ||
53 | .dma_mask = &jz4740_usb_ohci_device.dev.coherent_dma_mask, | ||
54 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
55 | }, | ||
56 | .num_resources = ARRAY_SIZE(jz4740_usb_ohci_resources), | ||
57 | .resource = jz4740_usb_ohci_resources, | ||
58 | }; | ||
59 | |||
60 | /* USB Device Controller */ | 35 | /* USB Device Controller */ |
61 | struct platform_device jz4740_udc_xceiv_device = { | 36 | struct platform_device jz4740_udc_xceiv_device = { |
62 | .name = "usb_phy_generic", | 37 | .name = "usb_phy_generic", |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index b0988fd62fcc..e6053d07072f 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -44,7 +44,7 @@ obj-$(CONFIG_CPU_CAVIUM_OCTEON) += r4k_fpu.o octeon_switch.o | |||
44 | 44 | ||
45 | obj-$(CONFIG_SMP) += smp.o | 45 | obj-$(CONFIG_SMP) += smp.o |
46 | obj-$(CONFIG_SMP_UP) += smp-up.o | 46 | obj-$(CONFIG_SMP_UP) += smp-up.o |
47 | obj-$(CONFIG_CPU_BMIPS) += smp-bmips.o bmips_vec.o | 47 | obj-$(CONFIG_CPU_BMIPS) += smp-bmips.o bmips_vec.o bmips_5xxx_init.o |
48 | 48 | ||
49 | obj-$(CONFIG_MIPS_MT) += mips-mt.o | 49 | obj-$(CONFIG_MIPS_MT) += mips-mt.o |
50 | obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o | 50 | obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o |
@@ -83,6 +83,8 @@ obj-$(CONFIG_I8253) += i8253.o | |||
83 | 83 | ||
84 | obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o | 84 | obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o |
85 | 85 | ||
86 | obj-$(CONFIG_RELOCATABLE) += relocate.o | ||
87 | |||
86 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o | 88 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o |
87 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | 89 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
88 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 90 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 154e2039ea5e..1ea973b2abb1 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/kbuild.h> | 15 | #include <linux/kbuild.h> |
16 | #include <linux/suspend.h> | 16 | #include <linux/suspend.h> |
17 | #include <asm/cpu-info.h> | ||
17 | #include <asm/pm.h> | 18 | #include <asm/pm.h> |
18 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
19 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
@@ -338,6 +339,15 @@ void output_pm_defines(void) | |||
338 | } | 339 | } |
339 | #endif | 340 | #endif |
340 | 341 | ||
342 | void output_cpuinfo_defines(void) | ||
343 | { | ||
344 | COMMENT(" MIPS cpuinfo offsets. "); | ||
345 | DEFINE(CPUINFO_SIZE, sizeof(struct cpuinfo_mips)); | ||
346 | #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE | ||
347 | OFFSET(CPUINFO_ASID_MASK, cpuinfo_mips, asid_mask); | ||
348 | #endif | ||
349 | } | ||
350 | |||
341 | void output_kvm_defines(void) | 351 | void output_kvm_defines(void) |
342 | { | 352 | { |
343 | COMMENT(" KVM/MIPS Specfic offsets. "); | 353 | COMMENT(" KVM/MIPS Specfic offsets. "); |
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 1b992c6e3d8e..58ad63d7eb42 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c | |||
@@ -30,21 +30,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | |||
30 | /* | 30 | /* |
31 | * This is used to ensure we don't load something for the wrong architecture. | 31 | * This is used to ensure we don't load something for the wrong architecture. |
32 | */ | 32 | */ |
33 | #define elf_check_arch(hdr) \ | 33 | #define elf_check_arch elfn32_check_arch |
34 | ({ \ | ||
35 | int __res = 1; \ | ||
36 | struct elfhdr *__h = (hdr); \ | ||
37 | \ | ||
38 | if (!mips_elf_check_machine(__h)) \ | ||
39 | __res = 0; \ | ||
40 | if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ | ||
41 | __res = 0; \ | ||
42 | if (((__h->e_flags & EF_MIPS_ABI2) == 0) || \ | ||
43 | ((__h->e_flags & EF_MIPS_ABI) != 0)) \ | ||
44 | __res = 0; \ | ||
45 | \ | ||
46 | __res; \ | ||
47 | }) | ||
48 | 34 | ||
49 | #define TASK32_SIZE 0x7fff8000UL | 35 | #define TASK32_SIZE 0x7fff8000UL |
50 | #undef ELF_ET_DYN_BASE | 36 | #undef ELF_ET_DYN_BASE |
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index abd3affe5fb3..49fb881481f7 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c | |||
@@ -28,39 +28,9 @@ typedef double elf_fpreg_t; | |||
28 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | 28 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * In order to be sure that we don't attempt to execute an O32 binary which | ||
32 | * requires 64 bit FP (FR=1) on a system which does not support it we refuse | ||
33 | * to execute any binary which has bits specified by the following macro set | ||
34 | * in its ELF header flags. | ||
35 | */ | ||
36 | #ifdef CONFIG_MIPS_O32_FP64_SUPPORT | ||
37 | # define __MIPS_O32_FP64_MUST_BE_ZERO 0 | ||
38 | #else | ||
39 | # define __MIPS_O32_FP64_MUST_BE_ZERO EF_MIPS_FP64 | ||
40 | #endif | ||
41 | |||
42 | /* | ||
43 | * This is used to ensure we don't load something for the wrong architecture. | 31 | * This is used to ensure we don't load something for the wrong architecture. |
44 | */ | 32 | */ |
45 | #define elf_check_arch(hdr) \ | 33 | #define elf_check_arch elfo32_check_arch |
46 | ({ \ | ||
47 | int __res = 1; \ | ||
48 | struct elfhdr *__h = (hdr); \ | ||
49 | \ | ||
50 | if (!mips_elf_check_machine(__h)) \ | ||
51 | __res = 0; \ | ||
52 | if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ | ||
53 | __res = 0; \ | ||
54 | if ((__h->e_flags & EF_MIPS_ABI2) != 0) \ | ||
55 | __res = 0; \ | ||
56 | if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ | ||
57 | ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ | ||
58 | __res = 0; \ | ||
59 | if (__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO) \ | ||
60 | __res = 0; \ | ||
61 | \ | ||
62 | __res; \ | ||
63 | }) | ||
64 | 34 | ||
65 | #ifdef CONFIG_KVM_GUEST | 35 | #ifdef CONFIG_KVM_GUEST |
66 | #define TASK32_SIZE 0x3fff8000UL | 36 | #define TASK32_SIZE 0x3fff8000UL |
diff --git a/arch/mips/kernel/bmips_5xxx_init.S b/arch/mips/kernel/bmips_5xxx_init.S new file mode 100644 index 000000000000..adaa82e00f2b --- /dev/null +++ b/arch/mips/kernel/bmips_5xxx_init.S | |||
@@ -0,0 +1,753 @@ | |||
1 | |||
2 | /* | ||
3 | * This file is subject to the terms and conditions of the GNU General Public | ||
4 | * License. See the file "COPYING" in the main directory of this archive | ||
5 | * for more details. | ||
6 | * | ||
7 | * Copyright (C) 2011-2012 by Broadcom Corporation | ||
8 | * | ||
9 | * Init for bmips 5000. | ||
10 | * Used to init second core in dual core 5000's. | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | |||
15 | #include <asm/asm.h> | ||
16 | #include <asm/asmmacro.h> | ||
17 | #include <asm/cacheops.h> | ||
18 | #include <asm/regdef.h> | ||
19 | #include <asm/mipsregs.h> | ||
20 | #include <asm/stackframe.h> | ||
21 | #include <asm/addrspace.h> | ||
22 | #include <asm/hazards.h> | ||
23 | #include <asm/bmips.h> | ||
24 | |||
25 | #ifdef CONFIG_CPU_BMIPS5000 | ||
26 | |||
27 | |||
28 | #define cacheop(kva, size, linesize, op) \ | ||
29 | .set noreorder ; \ | ||
30 | addu t1, kva, size ; \ | ||
31 | subu t2, linesize, 1 ; \ | ||
32 | not t2 ; \ | ||
33 | and t0, kva, t2 ; \ | ||
34 | addiu t1, t1, -1 ; \ | ||
35 | and t1, t2 ; \ | ||
36 | 9: cache op, 0(t0) ; \ | ||
37 | bne t0, t1, 9b ; \ | ||
38 | addu t0, linesize ; \ | ||
39 | .set reorder ; | ||
40 | |||
41 | |||
42 | |||
43 | #define IS_SHIFT 22 | ||
44 | #define IL_SHIFT 19 | ||
45 | #define IA_SHIFT 16 | ||
46 | #define DS_SHIFT 13 | ||
47 | #define DL_SHIFT 10 | ||
48 | #define DA_SHIFT 7 | ||
49 | #define IS_MASK 7 | ||
50 | #define IL_MASK 7 | ||
51 | #define IA_MASK 7 | ||
52 | #define DS_MASK 7 | ||
53 | #define DL_MASK 7 | ||
54 | #define DA_MASK 7 | ||
55 | #define ICE_MASK 0x80000000 | ||
56 | #define DCE_MASK 0x40000000 | ||
57 | |||
58 | #define CP0_BRCM_CONFIG0 $22, 0 | ||
59 | #define CP0_BRCM_MODE $22, 1 | ||
60 | #define CP0_CONFIG_K0_MASK 7 | ||
61 | |||
62 | #define CP0_ICACHE_TAG_LO $28 | ||
63 | #define CP0_ICACHE_DATA_LO $28, 1 | ||
64 | #define CP0_DCACHE_TAG_LO $28, 2 | ||
65 | #define CP0_D_SEC_CACHE_DATA_LO $28, 3 | ||
66 | #define CP0_ICACHE_TAG_HI $29 | ||
67 | #define CP0_ICACHE_DATA_HI $29, 1 | ||
68 | #define CP0_DCACHE_TAG_HI $29, 2 | ||
69 | |||
70 | #define CP0_BRCM_MODE_Luc_MASK (1 << 11) | ||
71 | #define CP0_BRCM_CONFIG0_CWF_MASK (1 << 20) | ||
72 | #define CP0_BRCM_CONFIG0_TSE_MASK (1 << 19) | ||
73 | #define CP0_BRCM_MODE_SET_MASK (1 << 7) | ||
74 | #define CP0_BRCM_MODE_ClkRATIO_MASK (7 << 4) | ||
75 | #define CP0_BRCM_MODE_BrPRED_MASK (3 << 24) | ||
76 | #define CP0_BRCM_MODE_BrPRED_SHIFT 24 | ||
77 | #define CP0_BRCM_MODE_BrHIST_MASK (0x1f << 20) | ||
78 | #define CP0_BRCM_MODE_BrHIST_SHIFT 20 | ||
79 | |||
80 | /* ZSC L2 Cache Register Access Register Definitions */ | ||
81 | #define BRCM_ZSC_ALL_REGS_SELECT 0x7 << 24 | ||
82 | |||
83 | #define BRCM_ZSC_CONFIG_REG 0 << 3 | ||
84 | #define BRCM_ZSC_REQ_BUFFER_REG 2 << 3 | ||
85 | #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG0 4 << 3 | ||
86 | #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG1 6 << 3 | ||
87 | #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG2 8 << 3 | ||
88 | |||
89 | #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG0 0xa << 3 | ||
90 | #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG1 0xc << 3 | ||
91 | |||
92 | #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG0 0xe << 3 | ||
93 | #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG1 0x10 << 3 | ||
94 | |||
95 | #define BRCM_ZSC_CONFIG_LMB1En 1 << (15) | ||
96 | #define BRCM_ZSC_CONFIG_LMB0En 1 << (14) | ||
97 | |||
98 | /* branch predition values */ | ||
99 | |||
100 | #define BRCM_BrPRED_ALL_TAKEN (0x0) | ||
101 | #define BRCM_BrPRED_ALL_NOT_TAKEN (0x1) | ||
102 | #define BRCM_BrPRED_BHT_ENABLE (0x2) | ||
103 | #define BRCM_BrPRED_PREDICT_BACKWARD (0x3) | ||
104 | |||
105 | |||
106 | |||
107 | .align 2 | ||
108 | /* | ||
109 | * Function: size_i_cache | ||
110 | * Arguments: None | ||
111 | * Returns: v0 = i cache size, v1 = I cache line size | ||
112 | * Description: compute the I-cache size and I-cache line size | ||
113 | * Trashes: v0, v1, a0, t0 | ||
114 | * | ||
115 | * pseudo code: | ||
116 | * | ||
117 | */ | ||
118 | |||
119 | LEAF(size_i_cache) | ||
120 | .set noreorder | ||
121 | |||
122 | mfc0 a0, CP0_CONFIG, 1 | ||
123 | move t0, a0 | ||
124 | |||
125 | /* | ||
126 | * Determine sets per way: IS | ||
127 | * | ||
128 | * This field contains the number of sets (i.e., indices) per way of | ||
129 | * the instruction cache: | ||
130 | * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k | ||
131 | * vi) 0x5 - 0x7: Reserved. | ||
132 | */ | ||
133 | |||
134 | srl a0, a0, IS_SHIFT | ||
135 | and a0, a0, IS_MASK | ||
136 | |||
137 | /* sets per way = (64<<IS) */ | ||
138 | |||
139 | li v0, 0x40 | ||
140 | sllv v0, v0, a0 | ||
141 | |||
142 | /* | ||
143 | * Determine line size | ||
144 | * | ||
145 | * This field contains the line size of the instruction cache: | ||
146 | * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii) | ||
147 | * 0x5: 64 bytes, iv) the rest: Reserved. | ||
148 | */ | ||
149 | |||
150 | move a0, t0 | ||
151 | |||
152 | srl a0, a0, IL_SHIFT | ||
153 | and a0, a0, IL_MASK | ||
154 | |||
155 | beqz a0, no_i_cache | ||
156 | nop | ||
157 | |||
158 | /* line size = 2 ^ (IL+1) */ | ||
159 | |||
160 | addi a0, a0, 1 | ||
161 | li v1, 1 | ||
162 | sll v1, v1, a0 | ||
163 | |||
164 | /* v0 now have sets per way, multiply it by line size now | ||
165 | * that will give the set size | ||
166 | */ | ||
167 | |||
168 | sll v0, v0, a0 | ||
169 | |||
170 | /* | ||
171 | * Determine set associativity | ||
172 | * | ||
173 | * This field contains the set associativity of the instruction cache. | ||
174 | * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3: | ||
175 | * 4-way, v) 0x4 - 0x7: Reserved. | ||
176 | */ | ||
177 | |||
178 | move a0, t0 | ||
179 | |||
180 | srl a0, a0, IA_SHIFT | ||
181 | and a0, a0, IA_MASK | ||
182 | addi a0, a0, 0x1 | ||
183 | |||
184 | /* v0 has the set size, multiply it by | ||
185 | * set associativiy, to get the cache size | ||
186 | */ | ||
187 | |||
188 | multu v0, a0 /*multu is interlocked, so no need to insert nops */ | ||
189 | mflo v0 | ||
190 | b 1f | ||
191 | nop | ||
192 | |||
193 | no_i_cache: | ||
194 | move v0, zero | ||
195 | move v1, zero | ||
196 | 1: | ||
197 | jr ra | ||
198 | nop | ||
199 | .set reorder | ||
200 | |||
201 | END(size_i_cache) | ||
202 | |||
203 | /* | ||
204 | * Function: size_d_cache | ||
205 | * Arguments: None | ||
206 | * Returns: v0 = d cache size, v1 = d cache line size | ||
207 | * Description: compute the D-cache size and D-cache line size. | ||
208 | * Trashes: v0, v1, a0, t0 | ||
209 | * | ||
210 | */ | ||
211 | |||
212 | LEAF(size_d_cache) | ||
213 | .set noreorder | ||
214 | |||
215 | mfc0 a0, CP0_CONFIG, 1 | ||
216 | move t0, a0 | ||
217 | |||
218 | /* | ||
219 | * Determine sets per way: IS | ||
220 | * | ||
221 | * This field contains the number of sets (i.e., indices) per way of | ||
222 | * the instruction cache: | ||
223 | * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k | ||
224 | * vi) 0x5 - 0x7: Reserved. | ||
225 | */ | ||
226 | |||
227 | srl a0, a0, DS_SHIFT | ||
228 | and a0, a0, DS_MASK | ||
229 | |||
230 | /* sets per way = (64<<IS) */ | ||
231 | |||
232 | li v0, 0x40 | ||
233 | sllv v0, v0, a0 | ||
234 | |||
235 | /* | ||
236 | * Determine line size | ||
237 | * | ||
238 | * This field contains the line size of the instruction cache: | ||
239 | * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii) | ||
240 | * 0x5: 64 bytes, iv) the rest: Reserved. | ||
241 | */ | ||
242 | move a0, t0 | ||
243 | |||
244 | srl a0, a0, DL_SHIFT | ||
245 | and a0, a0, DL_MASK | ||
246 | |||
247 | beqz a0, no_d_cache | ||
248 | nop | ||
249 | |||
250 | /* line size = 2 ^ (IL+1) */ | ||
251 | |||
252 | addi a0, a0, 1 | ||
253 | li v1, 1 | ||
254 | sll v1, v1, a0 | ||
255 | |||
256 | /* v0 now have sets per way, multiply it by line size now | ||
257 | * that will give the set size | ||
258 | */ | ||
259 | |||
260 | sll v0, v0, a0 | ||
261 | |||
262 | /* determine set associativity | ||
263 | * | ||
264 | * This field contains the set associativity of the instruction cache. | ||
265 | * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3: | ||
266 | * 4-way, v) 0x4 - 0x7: Reserved. | ||
267 | */ | ||
268 | |||
269 | move a0, t0 | ||
270 | |||
271 | srl a0, a0, DA_SHIFT | ||
272 | and a0, a0, DA_MASK | ||
273 | addi a0, a0, 0x1 | ||
274 | |||
275 | /* v0 has the set size, multiply it by | ||
276 | * set associativiy, to get the cache size | ||
277 | */ | ||
278 | |||
279 | multu v0, a0 /*multu is interlocked, so no need to insert nops */ | ||
280 | mflo v0 | ||
281 | |||
282 | b 1f | ||
283 | nop | ||
284 | |||
285 | no_d_cache: | ||
286 | move v0, zero | ||
287 | move v1, zero | ||
288 | 1: | ||
289 | jr ra | ||
290 | nop | ||
291 | .set reorder | ||
292 | |||
293 | END(size_d_cache) | ||
294 | |||
295 | |||
296 | /* | ||
297 | * Function: enable_ID | ||
298 | * Arguments: None | ||
299 | * Returns: None | ||
300 | * Description: Enable I and D caches, initialize I and D-caches, also set | ||
301 | * hardware delay for d-cache (TP0). | ||
302 | * Trashes: t0 | ||
303 | * | ||
304 | */ | ||
305 | .global enable_ID | ||
306 | .ent enable_ID | ||
307 | .set noreorder | ||
308 | enable_ID: | ||
309 | mfc0 t0, CP0_BRCM_CONFIG0 | ||
310 | or t0, t0, (ICE_MASK | DCE_MASK) | ||
311 | mtc0 t0, CP0_BRCM_CONFIG0 | ||
312 | jr ra | ||
313 | nop | ||
314 | |||
315 | .end enable_ID | ||
316 | .set reorder | ||
317 | |||
318 | |||
319 | /* | ||
320 | * Function: l1_init | ||
321 | * Arguments: None | ||
322 | * Returns: None | ||
323 | * Description: Enable I and D caches, and initialize I and D-caches | ||
324 | * Trashes: a0, v0, v1, t0, t1, t2, t8 | ||
325 | * | ||
326 | */ | ||
327 | .globl l1_init | ||
328 | .ent l1_init | ||
329 | .set noreorder | ||
330 | l1_init: | ||
331 | |||
332 | /* save return address */ | ||
333 | move t8, ra | ||
334 | |||
335 | |||
336 | /* initialize I and D cache Data and Tag registers. */ | ||
337 | mtc0 zero, CP0_ICACHE_TAG_LO | ||
338 | mtc0 zero, CP0_ICACHE_TAG_HI | ||
339 | mtc0 zero, CP0_ICACHE_DATA_LO | ||
340 | mtc0 zero, CP0_ICACHE_DATA_HI | ||
341 | mtc0 zero, CP0_DCACHE_TAG_LO | ||
342 | mtc0 zero, CP0_DCACHE_TAG_HI | ||
343 | |||
344 | /* Enable Caches before Clearing. If the caches are disabled | ||
345 | * then the cache operations to clear the cache will be ignored | ||
346 | */ | ||
347 | |||
348 | jal enable_ID | ||
349 | nop | ||
350 | |||
351 | jal size_i_cache /* v0 = i-cache size, v1 = i-cache line size */ | ||
352 | nop | ||
353 | |||
354 | /* run uncached in kseg 1 */ | ||
355 | la k0, 1f | ||
356 | lui k1, 0x2000 | ||
357 | or k0, k1, k0 | ||
358 | jr k0 | ||
359 | nop | ||
360 | 1: | ||
361 | |||
362 | /* | ||
363 | * set K0 cache mode | ||
364 | */ | ||
365 | |||
366 | mfc0 t0, CP0_CONFIG | ||
367 | and t0, t0, ~CP0_CONFIG_K0_MASK | ||
368 | or t0, t0, 3 /* Write Back mode */ | ||
369 | mtc0 t0, CP0_CONFIG | ||
370 | |||
371 | /* | ||
372 | * Initialize instruction cache. | ||
373 | */ | ||
374 | |||
375 | li a0, KSEG0 | ||
376 | cacheop(a0, v0, v1, Index_Store_Tag_I) | ||
377 | |||
378 | /* | ||
379 | * Now we can run from I-$, kseg 0 | ||
380 | */ | ||
381 | la k0, 1f | ||
382 | lui k1, 0x2000 | ||
383 | or k0, k1, k0 | ||
384 | xor k0, k1, k0 | ||
385 | jr k0 | ||
386 | nop | ||
387 | 1: | ||
388 | /* | ||
389 | * Initialize data cache. | ||
390 | */ | ||
391 | |||
392 | jal size_d_cache /* v0 = d-cache size, v1 = d-cache line size */ | ||
393 | nop | ||
394 | |||
395 | |||
396 | li a0, KSEG0 | ||
397 | cacheop(a0, v0, v1, Index_Store_Tag_D) | ||
398 | |||
399 | jr t8 | ||
400 | nop | ||
401 | |||
402 | .end l1_init | ||
403 | .set reorder | ||
404 | |||
405 | |||
406 | /* | ||
407 | * Function: set_other_config | ||
408 | * Arguments: none | ||
409 | * Returns: None | ||
410 | * Description: initialize other remainder configuration to defaults. | ||
411 | * Trashes: t0, t1 | ||
412 | * | ||
413 | * pseudo code: | ||
414 | * | ||
415 | */ | ||
416 | LEAF(set_other_config) | ||
417 | .set noreorder | ||
418 | |||
419 | /* enable Bus error for I-fetch */ | ||
420 | mfc0 t0, CP0_CACHEERR, 0 | ||
421 | li t1, 0x4 | ||
422 | or t0, t1 | ||
423 | mtc0 t0, CP0_CACHEERR, 0 | ||
424 | |||
425 | /* enable Bus error for Load */ | ||
426 | mfc0 t0, CP0_CACHEERR, 1 | ||
427 | li t1, 0x4 | ||
428 | or t0, t1 | ||
429 | mtc0 t0, CP0_CACHEERR, 1 | ||
430 | |||
431 | /* enable Bus Error for Store */ | ||
432 | mfc0 t0, CP0_CACHEERR, 2 | ||
433 | li t1, 0x4 | ||
434 | or t0, t1 | ||
435 | mtc0 t0, CP0_CACHEERR, 2 | ||
436 | |||
437 | jr ra | ||
438 | nop | ||
439 | .set reorder | ||
440 | END(set_other_config) | ||
441 | |||
442 | /* | ||
443 | * Function: set_branch_pred | ||
444 | * Arguments: none | ||
445 | * Returns: None | ||
446 | * Description: | ||
447 | * Trashes: t0, t1 | ||
448 | * | ||
449 | * pseudo code: | ||
450 | * | ||
451 | */ | ||
452 | |||
453 | LEAF(set_branch_pred) | ||
454 | .set noreorder | ||
455 | mfc0 t0, CP0_BRCM_MODE | ||
456 | li t1, ~(CP0_BRCM_MODE_BrPRED_MASK | CP0_BRCM_MODE_BrHIST_MASK ) | ||
457 | and t0, t0, t1 | ||
458 | |||
459 | /* enable Branch prediction */ | ||
460 | li t1, BRCM_BrPRED_BHT_ENABLE | ||
461 | sll t1, CP0_BRCM_MODE_BrPRED_SHIFT | ||
462 | or t0, t0, t1 | ||
463 | |||
464 | /* set history count to 8 */ | ||
465 | li t1, 8 | ||
466 | sll t1, CP0_BRCM_MODE_BrHIST_SHIFT | ||
467 | or t0, t0, t1 | ||
468 | |||
469 | mtc0 t0, CP0_BRCM_MODE | ||
470 | jr ra | ||
471 | nop | ||
472 | .set reorder | ||
473 | END(set_branch_pred) | ||
474 | |||
475 | |||
476 | /* | ||
477 | * Function: set_luc | ||
478 | * Arguments: set link uncached. | ||
479 | * Returns: None | ||
480 | * Description: | ||
481 | * Trashes: t0, t1 | ||
482 | * | ||
483 | */ | ||
484 | LEAF(set_luc) | ||
485 | .set noreorder | ||
486 | mfc0 t0, CP0_BRCM_MODE | ||
487 | li t1, ~(CP0_BRCM_MODE_Luc_MASK) | ||
488 | and t0, t0, t1 | ||
489 | |||
490 | /* set Luc */ | ||
491 | ori t0, t0, CP0_BRCM_MODE_Luc_MASK | ||
492 | |||
493 | mtc0 t0, CP0_BRCM_MODE | ||
494 | jr ra | ||
495 | nop | ||
496 | .set reorder | ||
497 | END(set_luc) | ||
498 | |||
499 | /* | ||
500 | * Function: set_cwf_tse | ||
501 | * Arguments: set CWF and TSE bits | ||
502 | * Returns: None | ||
503 | * Description: | ||
504 | * Trashes: t0, t1 | ||
505 | * | ||
506 | */ | ||
507 | LEAF(set_cwf_tse) | ||
508 | .set noreorder | ||
509 | mfc0 t0, CP0_BRCM_CONFIG0 | ||
510 | li t1, (CP0_BRCM_CONFIG0_CWF_MASK | CP0_BRCM_CONFIG0_TSE_MASK) | ||
511 | or t0, t0, t1 | ||
512 | |||
513 | mtc0 t0, CP0_BRCM_CONFIG0 | ||
514 | jr ra | ||
515 | nop | ||
516 | .set reorder | ||
517 | END(set_cwf_tse) | ||
518 | |||
519 | /* | ||
520 | * Function: set_clock_ratio | ||
521 | * Arguments: set clock ratio specified by a0 | ||
522 | * Returns: None | ||
523 | * Description: | ||
524 | * Trashes: v0, v1, a0, a1 | ||
525 | * | ||
526 | * pseudo code: | ||
527 | * | ||
528 | */ | ||
529 | LEAF(set_clock_ratio) | ||
530 | .set noreorder | ||
531 | |||
532 | mfc0 t0, CP0_BRCM_MODE | ||
533 | li t1, ~(CP0_BRCM_MODE_SET_MASK | CP0_BRCM_MODE_ClkRATIO_MASK) | ||
534 | and t0, t0, t1 | ||
535 | li t1, CP0_BRCM_MODE_SET_MASK | ||
536 | or t0, t0, t1 | ||
537 | or t0, t0, a0 | ||
538 | mtc0 t0, CP0_BRCM_MODE | ||
539 | jr ra | ||
540 | nop | ||
541 | .set reorder | ||
542 | END(set_clock_ratio) | ||
543 | /* | ||
544 | * Function: set_zephyr | ||
545 | * Arguments: None | ||
546 | * Returns: None | ||
547 | * Description: Set any zephyr bits | ||
548 | * Trashes: t0 & t1 | ||
549 | * | ||
550 | */ | ||
551 | LEAF(set_zephyr) | ||
552 | .set noreorder | ||
553 | |||
554 | /* enable read/write of CP0 #22 sel. 8 */ | ||
555 | li t0, 0x5a455048 | ||
556 | .word 0x4088b00f /* mtc0 t0, $22, 15 */ | ||
557 | |||
558 | .word 0x4008b008 /* mfc0 t0, $22, 8 */ | ||
559 | li t1, 0x09008000 /* turn off pref, jtb */ | ||
560 | or t0, t0, t1 | ||
561 | .word 0x4088b008 /* mtc0 t0, $22, 8 */ | ||
562 | sync | ||
563 | |||
564 | /* disable read/write of CP0 #22 sel 8 */ | ||
565 | li t0, 0x0 | ||
566 | .word 0x4088b00f /* mtc0 t0, $22, 15 */ | ||
567 | |||
568 | |||
569 | jr ra | ||
570 | nop | ||
571 | .set reorder | ||
572 | |||
573 | END(set_zephyr) | ||
574 | |||
575 | |||
576 | /* | ||
577 | * Function: set_llmb | ||
578 | * Arguments: a0=0 disable llmb, a0=1 enables llmb | ||
579 | * Returns: None | ||
580 | * Description: | ||
581 | * Trashes: t0, t1, t2 | ||
582 | * | ||
583 | * pseudo code: | ||
584 | * | ||
585 | */ | ||
586 | LEAF(set_llmb) | ||
587 | .set noreorder | ||
588 | |||
589 | li t2, 0x90000000 | BRCM_ZSC_ALL_REGS_SELECT | BRCM_ZSC_CONFIG_REG | ||
590 | sync | ||
591 | cache 0x7, 0x0(t2) | ||
592 | sync | ||
593 | mfc0 t0, CP0_D_SEC_CACHE_DATA_LO | ||
594 | li t1, ~(BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En) | ||
595 | and t0, t0, t1 | ||
596 | |||
597 | beqz a0, svlmb | ||
598 | nop | ||
599 | |||
600 | enable_lmb: | ||
601 | li t1, (BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En) | ||
602 | or t0, t0, t1 | ||
603 | |||
604 | svlmb: | ||
605 | mtc0 t0, CP0_D_SEC_CACHE_DATA_LO | ||
606 | sync | ||
607 | cache 0xb, 0x0(t2) | ||
608 | sync | ||
609 | |||
610 | jr ra | ||
611 | nop | ||
612 | .set reorder | ||
613 | |||
614 | END(set_llmb) | ||
615 | /* | ||
616 | * Function: core_init | ||
617 | * Arguments: none | ||
618 | * Returns: None | ||
619 | * Description: initialize core related configuration | ||
620 | * Trashes: v0,v1,a0,a1,t8 | ||
621 | * | ||
622 | * pseudo code: | ||
623 | * | ||
624 | */ | ||
625 | .globl core_init | ||
626 | .ent core_init | ||
627 | .set noreorder | ||
628 | core_init: | ||
629 | move t8, ra | ||
630 | |||
631 | /* set Zephyr bits. */ | ||
632 | bal set_zephyr | ||
633 | nop | ||
634 | |||
635 | #if ENABLE_FPU==1 | ||
636 | /* initialize the Floating point unit (both TPs) */ | ||
637 | bal init_fpu | ||
638 | nop | ||
639 | #endif | ||
640 | |||
641 | /* set low latency memory bus */ | ||
642 | li a0, 1 | ||
643 | bal set_llmb | ||
644 | nop | ||
645 | |||
646 | /* set branch prediction (TP0 only) */ | ||
647 | bal set_branch_pred | ||
648 | nop | ||
649 | |||
650 | /* set link uncached */ | ||
651 | bal set_luc | ||
652 | nop | ||
653 | |||
654 | /* set CWF and TSE */ | ||
655 | bal set_cwf_tse | ||
656 | nop | ||
657 | |||
658 | /* | ||
659 | *set clock ratio by setting 1 to 'set' | ||
660 | * and 0 to ClkRatio, (TP0 only) | ||
661 | */ | ||
662 | li a0, 0 | ||
663 | bal set_clock_ratio | ||
664 | nop | ||
665 | |||
666 | /* set other configuration to defaults */ | ||
667 | bal set_other_config | ||
668 | nop | ||
669 | |||
670 | move ra, t8 | ||
671 | jr ra | ||
672 | nop | ||
673 | |||
674 | .set reorder | ||
675 | .end core_init | ||
676 | |||
677 | /* | ||
678 | * Function: clear_jump_target_buffer | ||
679 | * Arguments: None | ||
680 | * Returns: None | ||
681 | * Description: | ||
682 | * Trashes: t0, t1, t2 | ||
683 | * | ||
684 | */ | ||
685 | #define RESET_CALL_RETURN_STACK_THIS_THREAD (0x06<<16) | ||
686 | #define RESET_JUMP_TARGET_BUFFER_THIS_THREAD (0x04<<16) | ||
687 | #define JTB_CS_CNTL_MASK (0xFF<<16) | ||
688 | |||
689 | .globl clear_jump_target_buffer | ||
690 | .ent clear_jump_target_buffer | ||
691 | .set noreorder | ||
692 | clear_jump_target_buffer: | ||
693 | |||
694 | mfc0 t0, $22, 2 | ||
695 | nop | ||
696 | nop | ||
697 | |||
698 | li t1, ~JTB_CS_CNTL_MASK | ||
699 | and t0, t0, t1 | ||
700 | li t2, RESET_CALL_RETURN_STACK_THIS_THREAD | ||
701 | or t0, t0, t2 | ||
702 | mtc0 t0, $22, 2 | ||
703 | nop | ||
704 | nop | ||
705 | |||
706 | and t0, t0, t1 | ||
707 | li t2, RESET_JUMP_TARGET_BUFFER_THIS_THREAD | ||
708 | or t0, t0, t2 | ||
709 | mtc0 t0, $22, 2 | ||
710 | nop | ||
711 | nop | ||
712 | jr ra | ||
713 | nop | ||
714 | |||
715 | .end clear_jump_target_buffer | ||
716 | .set reorder | ||
717 | /* | ||
718 | * Function: bmips_cache_init | ||
719 | * Arguments: None | ||
720 | * Returns: None | ||
721 | * Description: Enable I and D caches, and initialize I and D-caches | ||
722 | * Trashes: v0, v1, t0, t1, t2, t5, t7, t8 | ||
723 | * | ||
724 | */ | ||
725 | .globl bmips_5xxx_init | ||
726 | .ent bmips_5xxx_init | ||
727 | .set noreorder | ||
728 | bmips_5xxx_init: | ||
729 | |||
730 | /* save return address and A0 */ | ||
731 | move t7, ra | ||
732 | move t5, a0 | ||
733 | |||
734 | jal l1_init | ||
735 | nop | ||
736 | |||
737 | jal core_init | ||
738 | nop | ||
739 | |||
740 | jal clear_jump_target_buffer | ||
741 | nop | ||
742 | |||
743 | mtc0 zero, CP0_CAUSE | ||
744 | |||
745 | move a0, t5 | ||
746 | jr t7 | ||
747 | nop | ||
748 | |||
749 | .end bmips_5xxx_init | ||
750 | .set reorder | ||
751 | |||
752 | |||
753 | #endif | ||
diff --git a/arch/mips/kernel/bmips_vec.S b/arch/mips/kernel/bmips_vec.S index 86495072a922..921a5fa55da6 100644 --- a/arch/mips/kernel/bmips_vec.S +++ b/arch/mips/kernel/bmips_vec.S | |||
@@ -88,12 +88,13 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp) | |||
88 | li k1, (1 << 19) | 88 | li k1, (1 << 19) |
89 | mfc0 k0, CP0_STATUS | 89 | mfc0 k0, CP0_STATUS |
90 | and k0, k1 | 90 | and k0, k1 |
91 | beqz k0, bmips_smp_entry | 91 | beqz k0, soft_reset |
92 | 92 | ||
93 | #if defined(CONFIG_CPU_BMIPS5000) | 93 | #if defined(CONFIG_CPU_BMIPS5000) |
94 | mfc0 k0, CP0_PRID | 94 | mfc0 k0, CP0_PRID |
95 | li k1, PRID_IMP_BMIPS5000 | 95 | li k1, PRID_IMP_BMIPS5000 |
96 | andi k0, 0xff00 | 96 | /* mask with PRID_IMP_BMIPS5000 to cover both variants */ |
97 | andi k0, PRID_IMP_BMIPS5000 | ||
97 | bne k0, k1, 1f | 98 | bne k0, k1, 1f |
98 | 99 | ||
99 | /* if we're not on core 0, this must be the SMP boot signal */ | 100 | /* if we're not on core 0, this must be the SMP boot signal */ |
@@ -125,13 +126,48 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp) | |||
125 | .set arch=r4000 | 126 | .set arch=r4000 |
126 | eret | 127 | eret |
127 | 128 | ||
129 | #ifdef CONFIG_SMP | ||
130 | soft_reset: | ||
131 | |||
132 | #if defined(CONFIG_CPU_BMIPS5000) | ||
133 | mfc0 k0, CP0_PRID | ||
134 | andi k0, 0xff00 | ||
135 | li k1, PRID_IMP_BMIPS5200 | ||
136 | bne k0, k1, bmips_smp_entry | ||
137 | |||
138 | /* if running on TP 1, jump to bmips_smp_entry */ | ||
139 | mfc0 k0, $22 | ||
140 | li k1, (1 << 24) | ||
141 | and k1, k0 | ||
142 | bnez k1, bmips_smp_entry | ||
143 | nop | ||
144 | |||
145 | /* | ||
146 | * running on TP0, can not be core 0 (the boot core). | ||
147 | * Check for soft reset. Indicates a warm boot | ||
148 | */ | ||
149 | mfc0 k0, $12 | ||
150 | li k1, (1 << 20) | ||
151 | and k0, k1 | ||
152 | beqz k0, bmips_smp_entry | ||
153 | |||
154 | /* | ||
155 | * Warm boot. | ||
156 | * Cache init is only done on TP0 | ||
157 | */ | ||
158 | la k0, bmips_5xxx_init | ||
159 | jalr k0 | ||
160 | nop | ||
161 | |||
162 | b bmips_smp_entry | ||
163 | nop | ||
164 | #endif | ||
165 | |||
128 | /*********************************************************************** | 166 | /*********************************************************************** |
129 | * CPU1 reset vector (used for the initial boot only) | 167 | * CPU1 reset vector (used for the initial boot only) |
130 | * This is still part of bmips_reset_nmi_vec(). | 168 | * This is still part of bmips_reset_nmi_vec(). |
131 | ***********************************************************************/ | 169 | ***********************************************************************/ |
132 | 170 | ||
133 | #ifdef CONFIG_SMP | ||
134 | |||
135 | bmips_smp_entry: | 171 | bmips_smp_entry: |
136 | 172 | ||
137 | /* set up CP0 STATUS; enable FPU */ | 173 | /* set up CP0 STATUS; enable FPU */ |
@@ -166,10 +202,12 @@ bmips_smp_entry: | |||
166 | 2: | 202 | 2: |
167 | #endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */ | 203 | #endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */ |
168 | #if defined(CONFIG_CPU_BMIPS5000) | 204 | #if defined(CONFIG_CPU_BMIPS5000) |
169 | /* set exception vector base */ | 205 | /* mask with PRID_IMP_BMIPS5000 to cover both variants */ |
170 | li k1, PRID_IMP_BMIPS5000 | 206 | li k1, PRID_IMP_BMIPS5000 |
207 | andi k0, PRID_IMP_BMIPS5000 | ||
171 | bne k0, k1, 3f | 208 | bne k0, k1, 3f |
172 | 209 | ||
210 | /* set exception vector base */ | ||
173 | la k0, ebase | 211 | la k0, ebase |
174 | lw k0, 0(k0) | 212 | lw k0, 0(k0) |
175 | mtc0 k0, $15, 1 | 213 | mtc0 k0, $15, 1 |
@@ -263,6 +301,8 @@ LEAF(bmips_enable_xks01) | |||
263 | #endif /* CONFIG_CPU_BMIPS4380 */ | 301 | #endif /* CONFIG_CPU_BMIPS4380 */ |
264 | #if defined(CONFIG_CPU_BMIPS5000) | 302 | #if defined(CONFIG_CPU_BMIPS5000) |
265 | li t1, PRID_IMP_BMIPS5000 | 303 | li t1, PRID_IMP_BMIPS5000 |
304 | /* mask with PRID_IMP_BMIPS5000 to cover both variants */ | ||
305 | andi t2, PRID_IMP_BMIPS5000 | ||
266 | bne t2, t1, 2f | 306 | bne t2, t1, 2f |
267 | 307 | ||
268 | mfc0 t0, $22, 5 | 308 | mfc0 t0, $22, 5 |
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index d8f9b357b222..ceca6cc41b2b 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c | |||
@@ -688,21 +688,9 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, | |||
688 | } | 688 | } |
689 | lose_fpu(1); /* Save FPU state for the emulator. */ | 689 | lose_fpu(1); /* Save FPU state for the emulator. */ |
690 | reg = insn.i_format.rt; | 690 | reg = insn.i_format.rt; |
691 | bit = 0; | 691 | bit = get_fpr32(¤t->thread.fpu.fpr[reg], 0) & 0x1; |
692 | switch (insn.i_format.rs) { | 692 | if (insn.i_format.rs == bc1eqz_op) |
693 | case bc1eqz_op: | 693 | bit = !bit; |
694 | /* Test bit 0 */ | ||
695 | if (get_fpr32(¤t->thread.fpu.fpr[reg], 0) | ||
696 | & 0x1) | ||
697 | bit = 1; | ||
698 | break; | ||
699 | case bc1nez_op: | ||
700 | /* Test bit 0 */ | ||
701 | if (!(get_fpr32(¤t->thread.fpu.fpr[reg], 0) | ||
702 | & 0x1)) | ||
703 | bit = 1; | ||
704 | break; | ||
705 | } | ||
706 | own_fpu(1); | 694 | own_fpu(1); |
707 | if (bit) | 695 | if (bit) |
708 | epc = epc + 4 + | 696 | epc = epc + 4 + |
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 8dfe6a6e1480..e4c21bbf9422 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -28,6 +28,83 @@ static int mips_next_event(unsigned long delta, | |||
28 | return res; | 28 | return res; |
29 | } | 29 | } |
30 | 30 | ||
31 | /** | ||
32 | * calculate_min_delta() - Calculate a good minimum delta for mips_next_event(). | ||
33 | * | ||
34 | * Running under virtualisation can introduce overhead into mips_next_event() in | ||
35 | * the form of hypervisor emulation of CP0_Count/CP0_Compare registers, | ||
36 | * potentially with an unnatural frequency, which makes a fixed min_delta_ns | ||
37 | * value inappropriate as it may be too small. | ||
38 | * | ||
39 | * It can also introduce occasional latency from the guest being descheduled. | ||
40 | * | ||
41 | * This function calculates a good minimum delta based roughly on the 75th | ||
42 | * percentile of the time taken to do the mips_next_event() sequence, in order | ||
43 | * to handle potentially higher overhead while also eliminating outliers due to | ||
44 | * unpredictable hypervisor latency (which can be handled by retries). | ||
45 | * | ||
46 | * Return: An appropriate minimum delta for the clock event device. | ||
47 | */ | ||
48 | static unsigned int calculate_min_delta(void) | ||
49 | { | ||
50 | unsigned int cnt, i, j, k, l; | ||
51 | unsigned int buf1[4], buf2[3]; | ||
52 | unsigned int min_delta; | ||
53 | |||
54 | /* | ||
55 | * Calculate the median of 5 75th percentiles of 5 samples of how long | ||
56 | * it takes to set CP0_Compare = CP0_Count + delta. | ||
57 | */ | ||
58 | for (i = 0; i < 5; ++i) { | ||
59 | for (j = 0; j < 5; ++j) { | ||
60 | /* | ||
61 | * This is like the code in mips_next_event(), and | ||
62 | * directly measures the borderline "safe" delta. | ||
63 | */ | ||
64 | cnt = read_c0_count(); | ||
65 | write_c0_compare(cnt); | ||
66 | cnt = read_c0_count() - cnt; | ||
67 | |||
68 | /* Sorted insert into buf1 */ | ||
69 | for (k = 0; k < j; ++k) { | ||
70 | if (cnt < buf1[k]) { | ||
71 | l = min_t(unsigned int, | ||
72 | j, ARRAY_SIZE(buf1) - 1); | ||
73 | for (; l > k; --l) | ||
74 | buf1[l] = buf1[l - 1]; | ||
75 | break; | ||
76 | } | ||
77 | } | ||
78 | if (k < ARRAY_SIZE(buf1)) | ||
79 | buf1[k] = cnt; | ||
80 | } | ||
81 | |||
82 | /* Sorted insert of 75th percentile into buf2 */ | ||
83 | for (k = 0; k < i; ++k) { | ||
84 | if (buf1[ARRAY_SIZE(buf1) - 1] < buf2[k]) { | ||
85 | l = min_t(unsigned int, | ||
86 | i, ARRAY_SIZE(buf2) - 1); | ||
87 | for (; l > k; --l) | ||
88 | buf2[l] = buf2[l - 1]; | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | if (k < ARRAY_SIZE(buf2)) | ||
93 | buf2[k] = buf1[ARRAY_SIZE(buf1) - 1]; | ||
94 | } | ||
95 | |||
96 | /* Use 2 * median of 75th percentiles */ | ||
97 | min_delta = buf2[ARRAY_SIZE(buf2) - 1] * 2; | ||
98 | |||
99 | /* Don't go too low */ | ||
100 | if (min_delta < 0x300) | ||
101 | min_delta = 0x300; | ||
102 | |||
103 | pr_debug("%s: median 75th percentile=%#x, min_delta=%#x\n", | ||
104 | __func__, buf2[ARRAY_SIZE(buf2) - 1], min_delta); | ||
105 | return min_delta; | ||
106 | } | ||
107 | |||
31 | DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); | 108 | DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); |
32 | int cp0_timer_irq_installed; | 109 | int cp0_timer_irq_installed; |
33 | 110 | ||
@@ -177,7 +254,7 @@ int r4k_clockevent_init(void) | |||
177 | { | 254 | { |
178 | unsigned int cpu = smp_processor_id(); | 255 | unsigned int cpu = smp_processor_id(); |
179 | struct clock_event_device *cd; | 256 | struct clock_event_device *cd; |
180 | unsigned int irq; | 257 | unsigned int irq, min_delta; |
181 | 258 | ||
182 | if (!cpu_has_counter || !mips_hpt_frequency) | 259 | if (!cpu_has_counter || !mips_hpt_frequency) |
183 | return -ENXIO; | 260 | return -ENXIO; |
@@ -203,7 +280,8 @@ int r4k_clockevent_init(void) | |||
203 | 280 | ||
204 | /* Calculate the min / max delta */ | 281 | /* Calculate the min / max delta */ |
205 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | 282 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); |
206 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); | 283 | min_delta = calculate_min_delta(); |
284 | cd->min_delta_ns = clockevent_delta2ns(min_delta, cd); | ||
207 | 285 | ||
208 | cd->rating = 300; | 286 | cd->rating = 300; |
209 | cd->irq = irq; | 287 | cd->irq = irq; |
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S index ac81edd44563..51b98dc371b3 100644 --- a/arch/mips/kernel/cps-vec.S +++ b/arch/mips/kernel/cps-vec.S | |||
@@ -18,9 +18,12 @@ | |||
18 | #include <asm/mipsmtregs.h> | 18 | #include <asm/mipsmtregs.h> |
19 | #include <asm/pm.h> | 19 | #include <asm/pm.h> |
20 | 20 | ||
21 | #define GCR_CPC_BASE_OFS 0x0088 | ||
21 | #define GCR_CL_COHERENCE_OFS 0x2008 | 22 | #define GCR_CL_COHERENCE_OFS 0x2008 |
22 | #define GCR_CL_ID_OFS 0x2028 | 23 | #define GCR_CL_ID_OFS 0x2028 |
23 | 24 | ||
25 | #define CPC_CL_VC_RUN_OFS 0x2028 | ||
26 | |||
24 | .extern mips_cm_base | 27 | .extern mips_cm_base |
25 | 28 | ||
26 | .set noreorder | 29 | .set noreorder |
@@ -60,6 +63,37 @@ | |||
60 | nop | 63 | nop |
61 | .endm | 64 | .endm |
62 | 65 | ||
66 | /* | ||
67 | * Set dest to non-zero if the core supports MIPSr6 multithreading | ||
68 | * (ie. VPs), else zero. If MIPSr6 multithreading is not supported then | ||
69 | * branch to nomt. | ||
70 | */ | ||
71 | .macro has_vp dest, nomt | ||
72 | mfc0 \dest, CP0_CONFIG, 1 | ||
73 | bgez \dest, \nomt | ||
74 | mfc0 \dest, CP0_CONFIG, 2 | ||
75 | bgez \dest, \nomt | ||
76 | mfc0 \dest, CP0_CONFIG, 3 | ||
77 | bgez \dest, \nomt | ||
78 | mfc0 \dest, CP0_CONFIG, 4 | ||
79 | bgez \dest, \nomt | ||
80 | mfc0 \dest, CP0_CONFIG, 5 | ||
81 | andi \dest, \dest, MIPS_CONF5_VP | ||
82 | beqz \dest, \nomt | ||
83 | nop | ||
84 | .endm | ||
85 | |||
86 | /* Calculate an uncached address for the CM GCRs */ | ||
87 | .macro cmgcrb dest | ||
88 | .set push | ||
89 | .set noat | ||
90 | MFC0 $1, CP0_CMGCRBASE | ||
91 | PTR_SLL $1, $1, 4 | ||
92 | PTR_LI \dest, UNCAC_BASE | ||
93 | PTR_ADDU \dest, \dest, $1 | ||
94 | .set pop | ||
95 | .endm | ||
96 | |||
63 | .section .text.cps-vec | 97 | .section .text.cps-vec |
64 | .balign 0x1000 | 98 | .balign 0x1000 |
65 | 99 | ||
@@ -90,120 +124,64 @@ not_nmi: | |||
90 | li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS | 124 | li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS |
91 | mtc0 t0, CP0_STATUS | 125 | mtc0 t0, CP0_STATUS |
92 | 126 | ||
93 | /* | 127 | /* Skip cache & coherence setup if we're already coherent */ |
94 | * Clear the bits used to index the caches. Note that the architecture | 128 | cmgcrb v1 |
95 | * dictates that writing to any of TagLo or TagHi selects 0 or 2 should | 129 | lw s7, GCR_CL_COHERENCE_OFS(v1) |
96 | * be valid for all MIPS32 CPUs, even those for which said writes are | 130 | bnez s7, 1f |
97 | * unnecessary. | ||
98 | */ | ||
99 | mtc0 zero, CP0_TAGLO, 0 | ||
100 | mtc0 zero, CP0_TAGHI, 0 | ||
101 | mtc0 zero, CP0_TAGLO, 2 | ||
102 | mtc0 zero, CP0_TAGHI, 2 | ||
103 | ehb | ||
104 | |||
105 | /* Primary cache configuration is indicated by Config1 */ | ||
106 | mfc0 v0, CP0_CONFIG, 1 | ||
107 | |||
108 | /* Detect I-cache line size */ | ||
109 | _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ | ||
110 | beqz t0, icache_done | ||
111 | li t1, 2 | ||
112 | sllv t0, t1, t0 | ||
113 | |||
114 | /* Detect I-cache size */ | ||
115 | _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ | ||
116 | xori t2, t1, 0x7 | ||
117 | beqz t2, 1f | ||
118 | li t3, 32 | ||
119 | addiu t1, t1, 1 | ||
120 | sllv t1, t3, t1 | ||
121 | 1: /* At this point t1 == I-cache sets per way */ | ||
122 | _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ | ||
123 | addiu t2, t2, 1 | ||
124 | mul t1, t1, t0 | ||
125 | mul t1, t1, t2 | ||
126 | |||
127 | li a0, CKSEG0 | ||
128 | PTR_ADD a1, a0, t1 | ||
129 | 1: cache Index_Store_Tag_I, 0(a0) | ||
130 | PTR_ADD a0, a0, t0 | ||
131 | bne a0, a1, 1b | ||
132 | nop | 131 | nop |
133 | icache_done: | ||
134 | 132 | ||
135 | /* Detect D-cache line size */ | 133 | /* Initialize the L1 caches */ |
136 | _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ | 134 | jal mips_cps_cache_init |
137 | beqz t0, dcache_done | 135 | nop |
138 | li t1, 2 | ||
139 | sllv t0, t1, t0 | ||
140 | |||
141 | /* Detect D-cache size */ | ||
142 | _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ | ||
143 | xori t2, t1, 0x7 | ||
144 | beqz t2, 1f | ||
145 | li t3, 32 | ||
146 | addiu t1, t1, 1 | ||
147 | sllv t1, t3, t1 | ||
148 | 1: /* At this point t1 == D-cache sets per way */ | ||
149 | _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ | ||
150 | addiu t2, t2, 1 | ||
151 | mul t1, t1, t0 | ||
152 | mul t1, t1, t2 | ||
153 | 136 | ||
154 | li a0, CKSEG0 | 137 | /* Enter the coherent domain */ |
155 | PTR_ADDU a1, a0, t1 | 138 | li t0, 0xff |
156 | PTR_SUBU a1, a1, t0 | 139 | sw t0, GCR_CL_COHERENCE_OFS(v1) |
157 | 1: cache Index_Store_Tag_D, 0(a0) | 140 | ehb |
158 | bne a0, a1, 1b | ||
159 | PTR_ADD a0, a0, t0 | ||
160 | dcache_done: | ||
161 | 141 | ||
162 | /* Set Kseg0 CCA to that in s0 */ | 142 | /* Set Kseg0 CCA to that in s0 */ |
163 | mfc0 t0, CP0_CONFIG | 143 | 1: mfc0 t0, CP0_CONFIG |
164 | ori t0, 0x7 | 144 | ori t0, 0x7 |
165 | xori t0, 0x7 | 145 | xori t0, 0x7 |
166 | or t0, t0, s0 | 146 | or t0, t0, s0 |
167 | mtc0 t0, CP0_CONFIG | 147 | mtc0 t0, CP0_CONFIG |
168 | ehb | 148 | ehb |
169 | 149 | ||
170 | /* Calculate an uncached address for the CM GCRs */ | ||
171 | MFC0 v1, CP0_CMGCRBASE | ||
172 | PTR_SLL v1, v1, 4 | ||
173 | PTR_LI t0, UNCAC_BASE | ||
174 | PTR_ADDU v1, v1, t0 | ||
175 | |||
176 | /* Enter the coherent domain */ | ||
177 | li t0, 0xff | ||
178 | sw t0, GCR_CL_COHERENCE_OFS(v1) | ||
179 | ehb | ||
180 | |||
181 | /* Jump to kseg0 */ | 150 | /* Jump to kseg0 */ |
182 | PTR_LA t0, 1f | 151 | PTR_LA t0, 1f |
183 | jr t0 | 152 | jr t0 |
184 | nop | 153 | nop |
185 | 154 | ||
186 | /* | 155 | /* |
187 | * We're up, cached & coherent. Perform any further required core-level | 156 | * We're up, cached & coherent. Perform any EVA initialization necessary |
188 | * initialisation. | 157 | * before we access memory. |
189 | */ | 158 | */ |
190 | 1: jal mips_cps_core_init | 159 | 1: eva_init |
160 | |||
161 | /* Retrieve boot configuration pointers */ | ||
162 | jal mips_cps_get_bootcfg | ||
191 | nop | 163 | nop |
192 | 164 | ||
193 | /* Do any EVA initialization if necessary */ | 165 | /* Skip core-level init if we started up coherent */ |
194 | eva_init | 166 | bnez s7, 1f |
167 | nop | ||
168 | |||
169 | /* Perform any further required core-level initialisation */ | ||
170 | jal mips_cps_core_init | ||
171 | nop | ||
195 | 172 | ||
196 | /* | 173 | /* |
197 | * Boot any other VPEs within this core that should be online, and | 174 | * Boot any other VPEs within this core that should be online, and |
198 | * deactivate this VPE if it should be offline. | 175 | * deactivate this VPE if it should be offline. |
199 | */ | 176 | */ |
177 | move a1, t9 | ||
200 | jal mips_cps_boot_vpes | 178 | jal mips_cps_boot_vpes |
201 | nop | 179 | move a0, v0 |
202 | 180 | ||
203 | /* Off we go! */ | 181 | /* Off we go! */ |
204 | PTR_L t1, VPEBOOTCFG_PC(v0) | 182 | 1: PTR_L t1, VPEBOOTCFG_PC(v1) |
205 | PTR_L gp, VPEBOOTCFG_GP(v0) | 183 | PTR_L gp, VPEBOOTCFG_GP(v1) |
206 | PTR_L sp, VPEBOOTCFG_SP(v0) | 184 | PTR_L sp, VPEBOOTCFG_SP(v1) |
207 | jr t1 | 185 | jr t1 |
208 | nop | 186 | nop |
209 | END(mips_cps_core_entry) | 187 | END(mips_cps_core_entry) |
@@ -245,7 +223,6 @@ LEAF(excep_intex) | |||
245 | 223 | ||
246 | .org 0x480 | 224 | .org 0x480 |
247 | LEAF(excep_ejtag) | 225 | LEAF(excep_ejtag) |
248 | DUMP_EXCEP("EJTAG") | ||
249 | PTR_LA k0, ejtag_debug_handler | 226 | PTR_LA k0, ejtag_debug_handler |
250 | jr k0 | 227 | jr k0 |
251 | nop | 228 | nop |
@@ -323,22 +300,35 @@ LEAF(mips_cps_core_init) | |||
323 | nop | 300 | nop |
324 | END(mips_cps_core_init) | 301 | END(mips_cps_core_init) |
325 | 302 | ||
326 | LEAF(mips_cps_boot_vpes) | 303 | /** |
327 | /* Retrieve CM base address */ | 304 | * mips_cps_get_bootcfg() - retrieve boot configuration pointers |
328 | PTR_LA t0, mips_cm_base | 305 | * |
329 | PTR_L t0, 0(t0) | 306 | * Returns: pointer to struct core_boot_config in v0, pointer to |
330 | 307 | * struct vpe_boot_config in v1, VPE ID in t9 | |
308 | */ | ||
309 | LEAF(mips_cps_get_bootcfg) | ||
331 | /* Calculate a pointer to this cores struct core_boot_config */ | 310 | /* Calculate a pointer to this cores struct core_boot_config */ |
311 | cmgcrb t0 | ||
332 | lw t0, GCR_CL_ID_OFS(t0) | 312 | lw t0, GCR_CL_ID_OFS(t0) |
333 | li t1, COREBOOTCFG_SIZE | 313 | li t1, COREBOOTCFG_SIZE |
334 | mul t0, t0, t1 | 314 | mul t0, t0, t1 |
335 | PTR_LA t1, mips_cps_core_bootcfg | 315 | PTR_LA t1, mips_cps_core_bootcfg |
336 | PTR_L t1, 0(t1) | 316 | PTR_L t1, 0(t1) |
337 | PTR_ADDU t0, t0, t1 | 317 | PTR_ADDU v0, t0, t1 |
338 | 318 | ||
339 | /* Calculate this VPEs ID. If the core doesn't support MT use 0 */ | 319 | /* Calculate this VPEs ID. If the core doesn't support MT use 0 */ |
340 | li t9, 0 | 320 | li t9, 0 |
341 | #ifdef CONFIG_MIPS_MT_SMP | 321 | #if defined(CONFIG_CPU_MIPSR6) |
322 | has_vp ta2, 1f | ||
323 | |||
324 | /* | ||
325 | * Assume non-contiguous numbering. Perhaps some day we'll need | ||
326 | * to handle contiguous VP numbering, but no such systems yet | ||
327 | * exist. | ||
328 | */ | ||
329 | mfc0 t9, $3, 1 | ||
330 | andi t9, t9, 0xff | ||
331 | #elif defined(CONFIG_MIPS_MT_SMP) | ||
342 | has_mt ta2, 1f | 332 | has_mt ta2, 1f |
343 | 333 | ||
344 | /* Find the number of VPEs present in the core */ | 334 | /* Find the number of VPEs present in the core */ |
@@ -362,22 +352,43 @@ LEAF(mips_cps_boot_vpes) | |||
362 | 352 | ||
363 | 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */ | 353 | 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */ |
364 | li t1, VPEBOOTCFG_SIZE | 354 | li t1, VPEBOOTCFG_SIZE |
365 | mul v0, t9, t1 | 355 | mul v1, t9, t1 |
366 | PTR_L ta3, COREBOOTCFG_VPECONFIG(t0) | 356 | PTR_L ta3, COREBOOTCFG_VPECONFIG(v0) |
367 | PTR_ADDU v0, v0, ta3 | 357 | PTR_ADDU v1, v1, ta3 |
368 | |||
369 | #ifdef CONFIG_MIPS_MT_SMP | ||
370 | 358 | ||
371 | /* If the core doesn't support MT then return */ | ||
372 | bnez ta2, 1f | ||
373 | nop | ||
374 | jr ra | 359 | jr ra |
375 | nop | 360 | nop |
361 | END(mips_cps_get_bootcfg) | ||
362 | |||
363 | LEAF(mips_cps_boot_vpes) | ||
364 | PTR_L ta2, COREBOOTCFG_VPEMASK(a0) | ||
365 | PTR_L ta3, COREBOOTCFG_VPECONFIG(a0) | ||
366 | |||
367 | #if defined(CONFIG_CPU_MIPSR6) | ||
368 | |||
369 | has_vp t0, 5f | ||
370 | |||
371 | /* Find base address of CPC */ | ||
372 | cmgcrb t3 | ||
373 | PTR_L t1, GCR_CPC_BASE_OFS(t3) | ||
374 | PTR_LI t2, ~0x7fff | ||
375 | and t1, t1, t2 | ||
376 | PTR_LI t2, UNCAC_BASE | ||
377 | PTR_ADD t1, t1, t2 | ||
378 | |||
379 | /* Set VC_RUN to the VPE mask */ | ||
380 | PTR_S ta2, CPC_CL_VC_RUN_OFS(t1) | ||
381 | ehb | ||
382 | |||
383 | #elif defined(CONFIG_MIPS_MT) | ||
376 | 384 | ||
377 | .set push | 385 | .set push |
378 | .set mt | 386 | .set mt |
379 | 387 | ||
380 | 1: /* Enter VPE configuration state */ | 388 | /* If the core doesn't support MT then return */ |
389 | has_mt t0, 5f | ||
390 | |||
391 | /* Enter VPE configuration state */ | ||
381 | dvpe | 392 | dvpe |
382 | PTR_LA t1, 1f | 393 | PTR_LA t1, 1f |
383 | jr.hb t1 | 394 | jr.hb t1 |
@@ -388,7 +399,6 @@ LEAF(mips_cps_boot_vpes) | |||
388 | ehb | 399 | ehb |
389 | 400 | ||
390 | /* Loop through each VPE */ | 401 | /* Loop through each VPE */ |
391 | PTR_L ta2, COREBOOTCFG_VPEMASK(t0) | ||
392 | move t8, ta2 | 402 | move t8, ta2 |
393 | li ta1, 0 | 403 | li ta1, 0 |
394 | 404 | ||
@@ -465,7 +475,7 @@ LEAF(mips_cps_boot_vpes) | |||
465 | 475 | ||
466 | /* Check whether this VPE is meant to be running */ | 476 | /* Check whether this VPE is meant to be running */ |
467 | li t0, 1 | 477 | li t0, 1 |
468 | sll t0, t0, t9 | 478 | sll t0, t0, a1 |
469 | and t0, t0, t8 | 479 | and t0, t0, t8 |
470 | bnez t0, 2f | 480 | bnez t0, 2f |
471 | nop | 481 | nop |
@@ -482,10 +492,84 @@ LEAF(mips_cps_boot_vpes) | |||
482 | #endif /* CONFIG_MIPS_MT_SMP */ | 492 | #endif /* CONFIG_MIPS_MT_SMP */ |
483 | 493 | ||
484 | /* Return */ | 494 | /* Return */ |
485 | jr ra | 495 | 5: jr ra |
486 | nop | 496 | nop |
487 | END(mips_cps_boot_vpes) | 497 | END(mips_cps_boot_vpes) |
488 | 498 | ||
499 | LEAF(mips_cps_cache_init) | ||
500 | /* | ||
501 | * Clear the bits used to index the caches. Note that the architecture | ||
502 | * dictates that writing to any of TagLo or TagHi selects 0 or 2 should | ||
503 | * be valid for all MIPS32 CPUs, even those for which said writes are | ||
504 | * unnecessary. | ||
505 | */ | ||
506 | mtc0 zero, CP0_TAGLO, 0 | ||
507 | mtc0 zero, CP0_TAGHI, 0 | ||
508 | mtc0 zero, CP0_TAGLO, 2 | ||
509 | mtc0 zero, CP0_TAGHI, 2 | ||
510 | ehb | ||
511 | |||
512 | /* Primary cache configuration is indicated by Config1 */ | ||
513 | mfc0 v0, CP0_CONFIG, 1 | ||
514 | |||
515 | /* Detect I-cache line size */ | ||
516 | _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ | ||
517 | beqz t0, icache_done | ||
518 | li t1, 2 | ||
519 | sllv t0, t1, t0 | ||
520 | |||
521 | /* Detect I-cache size */ | ||
522 | _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ | ||
523 | xori t2, t1, 0x7 | ||
524 | beqz t2, 1f | ||
525 | li t3, 32 | ||
526 | addiu t1, t1, 1 | ||
527 | sllv t1, t3, t1 | ||
528 | 1: /* At this point t1 == I-cache sets per way */ | ||
529 | _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ | ||
530 | addiu t2, t2, 1 | ||
531 | mul t1, t1, t0 | ||
532 | mul t1, t1, t2 | ||
533 | |||
534 | li a0, CKSEG0 | ||
535 | PTR_ADD a1, a0, t1 | ||
536 | 1: cache Index_Store_Tag_I, 0(a0) | ||
537 | PTR_ADD a0, a0, t0 | ||
538 | bne a0, a1, 1b | ||
539 | nop | ||
540 | icache_done: | ||
541 | |||
542 | /* Detect D-cache line size */ | ||
543 | _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ | ||
544 | beqz t0, dcache_done | ||
545 | li t1, 2 | ||
546 | sllv t0, t1, t0 | ||
547 | |||
548 | /* Detect D-cache size */ | ||
549 | _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ | ||
550 | xori t2, t1, 0x7 | ||
551 | beqz t2, 1f | ||
552 | li t3, 32 | ||
553 | addiu t1, t1, 1 | ||
554 | sllv t1, t3, t1 | ||
555 | 1: /* At this point t1 == D-cache sets per way */ | ||
556 | _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ | ||
557 | addiu t2, t2, 1 | ||
558 | mul t1, t1, t0 | ||
559 | mul t1, t1, t2 | ||
560 | |||
561 | li a0, CKSEG0 | ||
562 | PTR_ADDU a1, a0, t1 | ||
563 | PTR_SUBU a1, a1, t0 | ||
564 | 1: cache Index_Store_Tag_D, 0(a0) | ||
565 | bne a0, a1, 1b | ||
566 | PTR_ADD a0, a0, t0 | ||
567 | dcache_done: | ||
568 | |||
569 | jr ra | ||
570 | nop | ||
571 | END(mips_cps_cache_init) | ||
572 | |||
489 | #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM) | 573 | #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM) |
490 | 574 | ||
491 | /* Calculate a pointer to this CPUs struct mips_static_suspend_state */ | 575 | /* Calculate a pointer to this CPUs struct mips_static_suspend_state */ |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b725b713b9f8..5ac5c3e23460 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -539,6 +539,7 @@ static int set_ftlb_enable(struct cpuinfo_mips *c, int enable) | |||
539 | switch (c->cputype) { | 539 | switch (c->cputype) { |
540 | case CPU_PROAPTIV: | 540 | case CPU_PROAPTIV: |
541 | case CPU_P5600: | 541 | case CPU_P5600: |
542 | case CPU_P6600: | ||
542 | /* proAptiv & related cores use Config6 to enable the FTLB */ | 543 | /* proAptiv & related cores use Config6 to enable the FTLB */ |
543 | config = read_c0_config6(); | 544 | config = read_c0_config6(); |
544 | /* Clear the old probability value */ | 545 | /* Clear the old probability value */ |
@@ -561,6 +562,19 @@ static int set_ftlb_enable(struct cpuinfo_mips *c, int enable) | |||
561 | write_c0_config7(config | (calculate_ftlb_probability(c) | 562 | write_c0_config7(config | (calculate_ftlb_probability(c) |
562 | << MIPS_CONF7_FTLBP_SHIFT)); | 563 | << MIPS_CONF7_FTLBP_SHIFT)); |
563 | break; | 564 | break; |
565 | case CPU_LOONGSON3: | ||
566 | /* Flush ITLB, DTLB, VTLB and FTLB */ | ||
567 | write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB | | ||
568 | LOONGSON_DIAG_VTLB | LOONGSON_DIAG_FTLB); | ||
569 | /* Loongson-3 cores use Config6 to enable the FTLB */ | ||
570 | config = read_c0_config6(); | ||
571 | if (enable) | ||
572 | /* Enable FTLB */ | ||
573 | write_c0_config6(config & ~MIPS_CONF6_FTLBDIS); | ||
574 | else | ||
575 | /* Disable FTLB */ | ||
576 | write_c0_config6(config | MIPS_CONF6_FTLBDIS); | ||
577 | break; | ||
564 | default: | 578 | default: |
565 | return 1; | 579 | return 1; |
566 | } | 580 | } |
@@ -634,6 +648,8 @@ static inline unsigned int decode_config1(struct cpuinfo_mips *c) | |||
634 | 648 | ||
635 | if (config1 & MIPS_CONF1_MD) | 649 | if (config1 & MIPS_CONF1_MD) |
636 | c->ases |= MIPS_ASE_MDMX; | 650 | c->ases |= MIPS_ASE_MDMX; |
651 | if (config1 & MIPS_CONF1_PC) | ||
652 | c->options |= MIPS_CPU_PERF; | ||
637 | if (config1 & MIPS_CONF1_WR) | 653 | if (config1 & MIPS_CONF1_WR) |
638 | c->options |= MIPS_CPU_WATCH; | 654 | c->options |= MIPS_CPU_WATCH; |
639 | if (config1 & MIPS_CONF1_CA) | 655 | if (config1 & MIPS_CONF1_CA) |
@@ -673,18 +689,25 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) | |||
673 | 689 | ||
674 | if (config3 & MIPS_CONF3_SM) { | 690 | if (config3 & MIPS_CONF3_SM) { |
675 | c->ases |= MIPS_ASE_SMARTMIPS; | 691 | c->ases |= MIPS_ASE_SMARTMIPS; |
676 | c->options |= MIPS_CPU_RIXI; | 692 | c->options |= MIPS_CPU_RIXI | MIPS_CPU_CTXTC; |
677 | } | 693 | } |
678 | if (config3 & MIPS_CONF3_RXI) | 694 | if (config3 & MIPS_CONF3_RXI) |
679 | c->options |= MIPS_CPU_RIXI; | 695 | c->options |= MIPS_CPU_RIXI; |
696 | if (config3 & MIPS_CONF3_CTXTC) | ||
697 | c->options |= MIPS_CPU_CTXTC; | ||
680 | if (config3 & MIPS_CONF3_DSP) | 698 | if (config3 & MIPS_CONF3_DSP) |
681 | c->ases |= MIPS_ASE_DSP; | 699 | c->ases |= MIPS_ASE_DSP; |
682 | if (config3 & MIPS_CONF3_DSP2P) | 700 | if (config3 & MIPS_CONF3_DSP2P) { |
683 | c->ases |= MIPS_ASE_DSP2P; | 701 | c->ases |= MIPS_ASE_DSP2P; |
702 | if (cpu_has_mips_r6) | ||
703 | c->ases |= MIPS_ASE_DSP3; | ||
704 | } | ||
684 | if (config3 & MIPS_CONF3_VINT) | 705 | if (config3 & MIPS_CONF3_VINT) |
685 | c->options |= MIPS_CPU_VINT; | 706 | c->options |= MIPS_CPU_VINT; |
686 | if (config3 & MIPS_CONF3_VEIC) | 707 | if (config3 & MIPS_CONF3_VEIC) |
687 | c->options |= MIPS_CPU_VEIC; | 708 | c->options |= MIPS_CPU_VEIC; |
709 | if (config3 & MIPS_CONF3_LPA) | ||
710 | c->options |= MIPS_CPU_LPA; | ||
688 | if (config3 & MIPS_CONF3_MT) | 711 | if (config3 & MIPS_CONF3_MT) |
689 | c->ases |= MIPS_ASE_MIPSMT; | 712 | c->ases |= MIPS_ASE_MIPSMT; |
690 | if (config3 & MIPS_CONF3_ULRI) | 713 | if (config3 & MIPS_CONF3_ULRI) |
@@ -695,6 +718,10 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) | |||
695 | c->ases |= MIPS_ASE_VZ; | 718 | c->ases |= MIPS_ASE_VZ; |
696 | if (config3 & MIPS_CONF3_SC) | 719 | if (config3 & MIPS_CONF3_SC) |
697 | c->options |= MIPS_CPU_SEGMENTS; | 720 | c->options |= MIPS_CPU_SEGMENTS; |
721 | if (config3 & MIPS_CONF3_BI) | ||
722 | c->options |= MIPS_CPU_BADINSTR; | ||
723 | if (config3 & MIPS_CONF3_BP) | ||
724 | c->options |= MIPS_CPU_BADINSTRP; | ||
698 | if (config3 & MIPS_CONF3_MSA) | 725 | if (config3 & MIPS_CONF3_MSA) |
699 | c->ases |= MIPS_ASE_MSA; | 726 | c->ases |= MIPS_ASE_MSA; |
700 | if (config3 & MIPS_CONF3_PW) { | 727 | if (config3 & MIPS_CONF3_PW) { |
@@ -715,6 +742,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) | |||
715 | unsigned int newcf4; | 742 | unsigned int newcf4; |
716 | unsigned int mmuextdef; | 743 | unsigned int mmuextdef; |
717 | unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE; | 744 | unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE; |
745 | unsigned long asid_mask; | ||
718 | 746 | ||
719 | config4 = read_c0_config4(); | 747 | config4 = read_c0_config4(); |
720 | 748 | ||
@@ -773,7 +801,20 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) | |||
773 | } | 801 | } |
774 | } | 802 | } |
775 | 803 | ||
776 | c->kscratch_mask = (config4 >> 16) & 0xff; | 804 | c->kscratch_mask = (config4 & MIPS_CONF4_KSCREXIST) |
805 | >> MIPS_CONF4_KSCREXIST_SHIFT; | ||
806 | |||
807 | asid_mask = MIPS_ENTRYHI_ASID; | ||
808 | if (config4 & MIPS_CONF4_AE) | ||
809 | asid_mask |= MIPS_ENTRYHI_ASIDX; | ||
810 | set_cpu_asid_mask(c, asid_mask); | ||
811 | |||
812 | /* | ||
813 | * Warn if the computed ASID mask doesn't match the mask the kernel | ||
814 | * is built for. This may indicate either a serious problem or an | ||
815 | * easy optimisation opportunity, but either way should be addressed. | ||
816 | */ | ||
817 | WARN_ON(asid_mask != cpu_asid_mask(c)); | ||
777 | 818 | ||
778 | return config4 & MIPS_CONF_M; | 819 | return config4 & MIPS_CONF_M; |
779 | } | 820 | } |
@@ -796,6 +837,8 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c) | |||
796 | if (config5 & MIPS_CONF5_MVH) | 837 | if (config5 & MIPS_CONF5_MVH) |
797 | c->options |= MIPS_CPU_XPA; | 838 | c->options |= MIPS_CPU_XPA; |
798 | #endif | 839 | #endif |
840 | if (cpu_has_mips_r6 && (config5 & MIPS_CONF5_VP)) | ||
841 | c->options |= MIPS_CPU_VP; | ||
799 | 842 | ||
800 | return config5 & MIPS_CONF_M; | 843 | return config5 & MIPS_CONF_M; |
801 | } | 844 | } |
@@ -826,17 +869,43 @@ static void decode_configs(struct cpuinfo_mips *c) | |||
826 | if (ok) | 869 | if (ok) |
827 | ok = decode_config5(c); | 870 | ok = decode_config5(c); |
828 | 871 | ||
829 | mips_probe_watch_registers(c); | 872 | /* Probe the EBase.WG bit */ |
830 | 873 | if (cpu_has_mips_r2_r6) { | |
831 | if (cpu_has_rixi) { | 874 | u64 ebase; |
832 | /* Enable the RIXI exceptions */ | 875 | unsigned int status; |
833 | set_c0_pagegrain(PG_IEC); | 876 | |
834 | back_to_back_c0_hazard(); | 877 | /* {read,write}_c0_ebase_64() may be UNDEFINED prior to r6 */ |
835 | /* Verify the IEC bit is set */ | 878 | ebase = cpu_has_mips64r6 ? read_c0_ebase_64() |
836 | if (read_c0_pagegrain() & PG_IEC) | 879 | : (s32)read_c0_ebase(); |
837 | c->options |= MIPS_CPU_RIXIEX; | 880 | if (ebase & MIPS_EBASE_WG) { |
881 | /* WG bit already set, we can avoid the clumsy probe */ | ||
882 | c->options |= MIPS_CPU_EBASE_WG; | ||
883 | } else { | ||
884 | /* Its UNDEFINED to change EBase while BEV=0 */ | ||
885 | status = read_c0_status(); | ||
886 | write_c0_status(status | ST0_BEV); | ||
887 | irq_enable_hazard(); | ||
888 | /* | ||
889 | * On pre-r6 cores, this may well clobber the upper bits | ||
890 | * of EBase. This is hard to avoid without potentially | ||
891 | * hitting UNDEFINED dm*c0 behaviour if EBase is 32-bit. | ||
892 | */ | ||
893 | if (cpu_has_mips64r6) | ||
894 | write_c0_ebase_64(ebase | MIPS_EBASE_WG); | ||
895 | else | ||
896 | write_c0_ebase(ebase | MIPS_EBASE_WG); | ||
897 | back_to_back_c0_hazard(); | ||
898 | /* Restore BEV */ | ||
899 | write_c0_status(status); | ||
900 | if (read_c0_ebase() & MIPS_EBASE_WG) { | ||
901 | c->options |= MIPS_CPU_EBASE_WG; | ||
902 | write_c0_ebase(ebase); | ||
903 | } | ||
904 | } | ||
838 | } | 905 | } |
839 | 906 | ||
907 | mips_probe_watch_registers(c); | ||
908 | |||
840 | #ifndef CONFIG_MIPS_CPS | 909 | #ifndef CONFIG_MIPS_CPS |
841 | if (cpu_has_mips_r2_r6) { | 910 | if (cpu_has_mips_r2_r6) { |
842 | c->core = get_ebase_cpunum(); | 911 | c->core = get_ebase_cpunum(); |
@@ -846,6 +915,235 @@ static void decode_configs(struct cpuinfo_mips *c) | |||
846 | #endif | 915 | #endif |
847 | } | 916 | } |
848 | 917 | ||
918 | /* | ||
919 | * Probe for certain guest capabilities by writing config bits and reading back. | ||
920 | * Finally write back the original value. | ||
921 | */ | ||
922 | #define probe_gc0_config(name, maxconf, bits) \ | ||
923 | do { \ | ||
924 | unsigned int tmp; \ | ||
925 | tmp = read_gc0_##name(); \ | ||
926 | write_gc0_##name(tmp | (bits)); \ | ||
927 | back_to_back_c0_hazard(); \ | ||
928 | maxconf = read_gc0_##name(); \ | ||
929 | write_gc0_##name(tmp); \ | ||
930 | } while (0) | ||
931 | |||
932 | /* | ||
933 | * Probe for dynamic guest capabilities by changing certain config bits and | ||
934 | * reading back to see if they change. Finally write back the original value. | ||
935 | */ | ||
936 | #define probe_gc0_config_dyn(name, maxconf, dynconf, bits) \ | ||
937 | do { \ | ||
938 | maxconf = read_gc0_##name(); \ | ||
939 | write_gc0_##name(maxconf ^ (bits)); \ | ||
940 | back_to_back_c0_hazard(); \ | ||
941 | dynconf = maxconf ^ read_gc0_##name(); \ | ||
942 | write_gc0_##name(maxconf); \ | ||
943 | maxconf |= dynconf; \ | ||
944 | } while (0) | ||
945 | |||
946 | static inline unsigned int decode_guest_config0(struct cpuinfo_mips *c) | ||
947 | { | ||
948 | unsigned int config0; | ||
949 | |||
950 | probe_gc0_config(config, config0, MIPS_CONF_M); | ||
951 | |||
952 | if (config0 & MIPS_CONF_M) | ||
953 | c->guest.conf |= BIT(1); | ||
954 | return config0 & MIPS_CONF_M; | ||
955 | } | ||
956 | |||
957 | static inline unsigned int decode_guest_config1(struct cpuinfo_mips *c) | ||
958 | { | ||
959 | unsigned int config1, config1_dyn; | ||
960 | |||
961 | probe_gc0_config_dyn(config1, config1, config1_dyn, | ||
962 | MIPS_CONF_M | MIPS_CONF1_PC | MIPS_CONF1_WR | | ||
963 | MIPS_CONF1_FP); | ||
964 | |||
965 | if (config1 & MIPS_CONF1_FP) | ||
966 | c->guest.options |= MIPS_CPU_FPU; | ||
967 | if (config1_dyn & MIPS_CONF1_FP) | ||
968 | c->guest.options_dyn |= MIPS_CPU_FPU; | ||
969 | |||
970 | if (config1 & MIPS_CONF1_WR) | ||
971 | c->guest.options |= MIPS_CPU_WATCH; | ||
972 | if (config1_dyn & MIPS_CONF1_WR) | ||
973 | c->guest.options_dyn |= MIPS_CPU_WATCH; | ||
974 | |||
975 | if (config1 & MIPS_CONF1_PC) | ||
976 | c->guest.options |= MIPS_CPU_PERF; | ||
977 | if (config1_dyn & MIPS_CONF1_PC) | ||
978 | c->guest.options_dyn |= MIPS_CPU_PERF; | ||
979 | |||
980 | if (config1 & MIPS_CONF_M) | ||
981 | c->guest.conf |= BIT(2); | ||
982 | return config1 & MIPS_CONF_M; | ||
983 | } | ||
984 | |||
985 | static inline unsigned int decode_guest_config2(struct cpuinfo_mips *c) | ||
986 | { | ||
987 | unsigned int config2; | ||
988 | |||
989 | probe_gc0_config(config2, config2, MIPS_CONF_M); | ||
990 | |||
991 | if (config2 & MIPS_CONF_M) | ||
992 | c->guest.conf |= BIT(3); | ||
993 | return config2 & MIPS_CONF_M; | ||
994 | } | ||
995 | |||
996 | static inline unsigned int decode_guest_config3(struct cpuinfo_mips *c) | ||
997 | { | ||
998 | unsigned int config3, config3_dyn; | ||
999 | |||
1000 | probe_gc0_config_dyn(config3, config3, config3_dyn, | ||
1001 | MIPS_CONF_M | MIPS_CONF3_MSA | MIPS_CONF3_CTXTC); | ||
1002 | |||
1003 | if (config3 & MIPS_CONF3_CTXTC) | ||
1004 | c->guest.options |= MIPS_CPU_CTXTC; | ||
1005 | if (config3_dyn & MIPS_CONF3_CTXTC) | ||
1006 | c->guest.options_dyn |= MIPS_CPU_CTXTC; | ||
1007 | |||
1008 | if (config3 & MIPS_CONF3_PW) | ||
1009 | c->guest.options |= MIPS_CPU_HTW; | ||
1010 | |||
1011 | if (config3 & MIPS_CONF3_SC) | ||
1012 | c->guest.options |= MIPS_CPU_SEGMENTS; | ||
1013 | |||
1014 | if (config3 & MIPS_CONF3_BI) | ||
1015 | c->guest.options |= MIPS_CPU_BADINSTR; | ||
1016 | if (config3 & MIPS_CONF3_BP) | ||
1017 | c->guest.options |= MIPS_CPU_BADINSTRP; | ||
1018 | |||
1019 | if (config3 & MIPS_CONF3_MSA) | ||
1020 | c->guest.ases |= MIPS_ASE_MSA; | ||
1021 | if (config3_dyn & MIPS_CONF3_MSA) | ||
1022 | c->guest.ases_dyn |= MIPS_ASE_MSA; | ||
1023 | |||
1024 | if (config3 & MIPS_CONF_M) | ||
1025 | c->guest.conf |= BIT(4); | ||
1026 | return config3 & MIPS_CONF_M; | ||
1027 | } | ||
1028 | |||
1029 | static inline unsigned int decode_guest_config4(struct cpuinfo_mips *c) | ||
1030 | { | ||
1031 | unsigned int config4; | ||
1032 | |||
1033 | probe_gc0_config(config4, config4, | ||
1034 | MIPS_CONF_M | MIPS_CONF4_KSCREXIST); | ||
1035 | |||
1036 | c->guest.kscratch_mask = (config4 & MIPS_CONF4_KSCREXIST) | ||
1037 | >> MIPS_CONF4_KSCREXIST_SHIFT; | ||
1038 | |||
1039 | if (config4 & MIPS_CONF_M) | ||
1040 | c->guest.conf |= BIT(5); | ||
1041 | return config4 & MIPS_CONF_M; | ||
1042 | } | ||
1043 | |||
1044 | static inline unsigned int decode_guest_config5(struct cpuinfo_mips *c) | ||
1045 | { | ||
1046 | unsigned int config5, config5_dyn; | ||
1047 | |||
1048 | probe_gc0_config_dyn(config5, config5, config5_dyn, | ||
1049 | MIPS_CONF_M | MIPS_CONF5_MRP); | ||
1050 | |||
1051 | if (config5 & MIPS_CONF5_MRP) | ||
1052 | c->guest.options |= MIPS_CPU_MAAR; | ||
1053 | if (config5_dyn & MIPS_CONF5_MRP) | ||
1054 | c->guest.options_dyn |= MIPS_CPU_MAAR; | ||
1055 | |||
1056 | if (config5 & MIPS_CONF5_LLB) | ||
1057 | c->guest.options |= MIPS_CPU_RW_LLB; | ||
1058 | |||
1059 | if (config5 & MIPS_CONF_M) | ||
1060 | c->guest.conf |= BIT(6); | ||
1061 | return config5 & MIPS_CONF_M; | ||
1062 | } | ||
1063 | |||
1064 | static inline void decode_guest_configs(struct cpuinfo_mips *c) | ||
1065 | { | ||
1066 | unsigned int ok; | ||
1067 | |||
1068 | ok = decode_guest_config0(c); | ||
1069 | if (ok) | ||
1070 | ok = decode_guest_config1(c); | ||
1071 | if (ok) | ||
1072 | ok = decode_guest_config2(c); | ||
1073 | if (ok) | ||
1074 | ok = decode_guest_config3(c); | ||
1075 | if (ok) | ||
1076 | ok = decode_guest_config4(c); | ||
1077 | if (ok) | ||
1078 | decode_guest_config5(c); | ||
1079 | } | ||
1080 | |||
1081 | static inline void cpu_probe_guestctl0(struct cpuinfo_mips *c) | ||
1082 | { | ||
1083 | unsigned int guestctl0, temp; | ||
1084 | |||
1085 | guestctl0 = read_c0_guestctl0(); | ||
1086 | |||
1087 | if (guestctl0 & MIPS_GCTL0_G0E) | ||
1088 | c->options |= MIPS_CPU_GUESTCTL0EXT; | ||
1089 | if (guestctl0 & MIPS_GCTL0_G1) | ||
1090 | c->options |= MIPS_CPU_GUESTCTL1; | ||
1091 | if (guestctl0 & MIPS_GCTL0_G2) | ||
1092 | c->options |= MIPS_CPU_GUESTCTL2; | ||
1093 | if (!(guestctl0 & MIPS_GCTL0_RAD)) { | ||
1094 | c->options |= MIPS_CPU_GUESTID; | ||
1095 | |||
1096 | /* | ||
1097 | * Probe for Direct Root to Guest (DRG). Set GuestCtl1.RID = 0 | ||
1098 | * first, otherwise all data accesses will be fully virtualised | ||
1099 | * as if they were performed by guest mode. | ||
1100 | */ | ||
1101 | write_c0_guestctl1(0); | ||
1102 | tlbw_use_hazard(); | ||
1103 | |||
1104 | write_c0_guestctl0(guestctl0 | MIPS_GCTL0_DRG); | ||
1105 | back_to_back_c0_hazard(); | ||
1106 | temp = read_c0_guestctl0(); | ||
1107 | |||
1108 | if (temp & MIPS_GCTL0_DRG) { | ||
1109 | write_c0_guestctl0(guestctl0); | ||
1110 | c->options |= MIPS_CPU_DRG; | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | static inline void cpu_probe_guestctl1(struct cpuinfo_mips *c) | ||
1116 | { | ||
1117 | if (cpu_has_guestid) { | ||
1118 | /* determine the number of bits of GuestID available */ | ||
1119 | write_c0_guestctl1(MIPS_GCTL1_ID); | ||
1120 | back_to_back_c0_hazard(); | ||
1121 | c->guestid_mask = (read_c0_guestctl1() & MIPS_GCTL1_ID) | ||
1122 | >> MIPS_GCTL1_ID_SHIFT; | ||
1123 | write_c0_guestctl1(0); | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | static inline void cpu_probe_gtoffset(struct cpuinfo_mips *c) | ||
1128 | { | ||
1129 | /* determine the number of bits of GTOffset available */ | ||
1130 | write_c0_gtoffset(0xffffffff); | ||
1131 | back_to_back_c0_hazard(); | ||
1132 | c->gtoffset_mask = read_c0_gtoffset(); | ||
1133 | write_c0_gtoffset(0); | ||
1134 | } | ||
1135 | |||
1136 | static inline void cpu_probe_vz(struct cpuinfo_mips *c) | ||
1137 | { | ||
1138 | cpu_probe_guestctl0(c); | ||
1139 | if (cpu_has_guestctl1) | ||
1140 | cpu_probe_guestctl1(c); | ||
1141 | |||
1142 | cpu_probe_gtoffset(c); | ||
1143 | |||
1144 | decode_guest_configs(c); | ||
1145 | } | ||
1146 | |||
849 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ | 1147 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ |
850 | | MIPS_CPU_COUNTER) | 1148 | | MIPS_CPU_COUNTER) |
851 | 1149 | ||
@@ -1172,7 +1470,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
1172 | set_isa(c, MIPS_CPU_ISA_III); | 1470 | set_isa(c, MIPS_CPU_ISA_III); |
1173 | c->fpu_msk31 |= FPU_CSR_CONDX; | 1471 | c->fpu_msk31 |= FPU_CSR_CONDX; |
1174 | break; | 1472 | break; |
1175 | case PRID_REV_LOONGSON3A: | 1473 | case PRID_REV_LOONGSON3A_R1: |
1176 | c->cputype = CPU_LOONGSON3; | 1474 | c->cputype = CPU_LOONGSON3; |
1177 | __cpu_name[cpu] = "ICT Loongson-3"; | 1475 | __cpu_name[cpu] = "ICT Loongson-3"; |
1178 | set_elf_platform(cpu, "loongson3a"); | 1476 | set_elf_platform(cpu, "loongson3a"); |
@@ -1314,6 +1612,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |||
1314 | c->cputype = CPU_P5600; | 1612 | c->cputype = CPU_P5600; |
1315 | __cpu_name[cpu] = "MIPS P5600"; | 1613 | __cpu_name[cpu] = "MIPS P5600"; |
1316 | break; | 1614 | break; |
1615 | case PRID_IMP_P6600: | ||
1616 | c->cputype = CPU_P6600; | ||
1617 | __cpu_name[cpu] = "MIPS P6600"; | ||
1618 | break; | ||
1317 | case PRID_IMP_I6400: | 1619 | case PRID_IMP_I6400: |
1318 | c->cputype = CPU_I6400; | 1620 | c->cputype = CPU_I6400; |
1319 | __cpu_name[cpu] = "MIPS I6400"; | 1621 | __cpu_name[cpu] = "MIPS I6400"; |
@@ -1322,6 +1624,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |||
1322 | c->cputype = CPU_M5150; | 1624 | c->cputype = CPU_M5150; |
1323 | __cpu_name[cpu] = "MIPS M5150"; | 1625 | __cpu_name[cpu] = "MIPS M5150"; |
1324 | break; | 1626 | break; |
1627 | case PRID_IMP_M6250: | ||
1628 | c->cputype = CPU_M6250; | ||
1629 | __cpu_name[cpu] = "MIPS M6250"; | ||
1630 | break; | ||
1325 | } | 1631 | } |
1326 | 1632 | ||
1327 | decode_configs(c); | 1633 | decode_configs(c); |
@@ -1435,6 +1741,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
1435 | c->cputype = CPU_BMIPS4380; | 1741 | c->cputype = CPU_BMIPS4380; |
1436 | __cpu_name[cpu] = "Broadcom BMIPS4380"; | 1742 | __cpu_name[cpu] = "Broadcom BMIPS4380"; |
1437 | set_elf_platform(cpu, "bmips4380"); | 1743 | set_elf_platform(cpu, "bmips4380"); |
1744 | c->options |= MIPS_CPU_RIXI; | ||
1438 | } else { | 1745 | } else { |
1439 | c->cputype = CPU_BMIPS4350; | 1746 | c->cputype = CPU_BMIPS4350; |
1440 | __cpu_name[cpu] = "Broadcom BMIPS4350"; | 1747 | __cpu_name[cpu] = "Broadcom BMIPS4350"; |
@@ -1445,9 +1752,12 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
1445 | case PRID_IMP_BMIPS5000: | 1752 | case PRID_IMP_BMIPS5000: |
1446 | case PRID_IMP_BMIPS5200: | 1753 | case PRID_IMP_BMIPS5200: |
1447 | c->cputype = CPU_BMIPS5000; | 1754 | c->cputype = CPU_BMIPS5000; |
1448 | __cpu_name[cpu] = "Broadcom BMIPS5000"; | 1755 | if ((c->processor_id & PRID_IMP_MASK) == PRID_IMP_BMIPS5200) |
1756 | __cpu_name[cpu] = "Broadcom BMIPS5200"; | ||
1757 | else | ||
1758 | __cpu_name[cpu] = "Broadcom BMIPS5000"; | ||
1449 | set_elf_platform(cpu, "bmips5000"); | 1759 | set_elf_platform(cpu, "bmips5000"); |
1450 | c->options |= MIPS_CPU_ULRI; | 1760 | c->options |= MIPS_CPU_ULRI | MIPS_CPU_RIXI; |
1451 | break; | 1761 | break; |
1452 | } | 1762 | } |
1453 | } | 1763 | } |
@@ -1481,6 +1791,8 @@ platform: | |||
1481 | set_elf_platform(cpu, "octeon2"); | 1791 | set_elf_platform(cpu, "octeon2"); |
1482 | break; | 1792 | break; |
1483 | case PRID_IMP_CAVIUM_CN70XX: | 1793 | case PRID_IMP_CAVIUM_CN70XX: |
1794 | case PRID_IMP_CAVIUM_CN73XX: | ||
1795 | case PRID_IMP_CAVIUM_CNF75XX: | ||
1484 | case PRID_IMP_CAVIUM_CN78XX: | 1796 | case PRID_IMP_CAVIUM_CN78XX: |
1485 | c->cputype = CPU_CAVIUM_OCTEON3; | 1797 | c->cputype = CPU_CAVIUM_OCTEON3; |
1486 | __cpu_name[cpu] = "Cavium Octeon III"; | 1798 | __cpu_name[cpu] = "Cavium Octeon III"; |
@@ -1493,6 +1805,29 @@ platform: | |||
1493 | } | 1805 | } |
1494 | } | 1806 | } |
1495 | 1807 | ||
1808 | static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) | ||
1809 | { | ||
1810 | switch (c->processor_id & PRID_IMP_MASK) { | ||
1811 | case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */ | ||
1812 | switch (c->processor_id & PRID_REV_MASK) { | ||
1813 | case PRID_REV_LOONGSON3A_R2: | ||
1814 | c->cputype = CPU_LOONGSON3; | ||
1815 | __cpu_name[cpu] = "ICT Loongson-3"; | ||
1816 | set_elf_platform(cpu, "loongson3a"); | ||
1817 | set_isa(c, MIPS_CPU_ISA_M64R2); | ||
1818 | break; | ||
1819 | } | ||
1820 | |||
1821 | decode_configs(c); | ||
1822 | c->options |= MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; | ||
1823 | c->writecombine = _CACHE_UNCACHED_ACCELERATED; | ||
1824 | break; | ||
1825 | default: | ||
1826 | panic("Unknown Loongson Processor ID!"); | ||
1827 | break; | ||
1828 | } | ||
1829 | } | ||
1830 | |||
1496 | static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) | 1831 | static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) |
1497 | { | 1832 | { |
1498 | decode_configs(c); | 1833 | decode_configs(c); |
@@ -1640,6 +1975,9 @@ void cpu_probe(void) | |||
1640 | case PRID_COMP_CAVIUM: | 1975 | case PRID_COMP_CAVIUM: |
1641 | cpu_probe_cavium(c, cpu); | 1976 | cpu_probe_cavium(c, cpu); |
1642 | break; | 1977 | break; |
1978 | case PRID_COMP_LOONGSON: | ||
1979 | cpu_probe_loongson(c, cpu); | ||
1980 | break; | ||
1643 | case PRID_COMP_INGENIC_D0: | 1981 | case PRID_COMP_INGENIC_D0: |
1644 | case PRID_COMP_INGENIC_D1: | 1982 | case PRID_COMP_INGENIC_D1: |
1645 | case PRID_COMP_INGENIC_E1: | 1983 | case PRID_COMP_INGENIC_E1: |
@@ -1660,6 +1998,15 @@ void cpu_probe(void) | |||
1660 | */ | 1998 | */ |
1661 | BUG_ON(current_cpu_type() != c->cputype); | 1999 | BUG_ON(current_cpu_type() != c->cputype); |
1662 | 2000 | ||
2001 | if (cpu_has_rixi) { | ||
2002 | /* Enable the RIXI exceptions */ | ||
2003 | set_c0_pagegrain(PG_IEC); | ||
2004 | back_to_back_c0_hazard(); | ||
2005 | /* Verify the IEC bit is set */ | ||
2006 | if (read_c0_pagegrain() & PG_IEC) | ||
2007 | c->options |= MIPS_CPU_RIXIEX; | ||
2008 | } | ||
2009 | |||
1663 | if (mips_fpu_disabled) | 2010 | if (mips_fpu_disabled) |
1664 | c->options &= ~MIPS_CPU_FPU; | 2011 | c->options &= ~MIPS_CPU_FPU; |
1665 | 2012 | ||
@@ -1699,6 +2046,9 @@ void cpu_probe(void) | |||
1699 | elf_hwcap |= HWCAP_MIPS_MSA; | 2046 | elf_hwcap |= HWCAP_MIPS_MSA; |
1700 | } | 2047 | } |
1701 | 2048 | ||
2049 | if (cpu_has_vz) | ||
2050 | cpu_probe_vz(c); | ||
2051 | |||
1702 | cpu_probe_vmbits(c); | 2052 | cpu_probe_vmbits(c); |
1703 | 2053 | ||
1704 | #ifdef CONFIG_64BIT | 2054 | #ifdef CONFIG_64BIT |
diff --git a/arch/mips/kernel/crash.c b/arch/mips/kernel/crash.c index d434d5d5ae6e..610f0f3bdb34 100644 --- a/arch/mips/kernel/crash.c +++ b/arch/mips/kernel/crash.c | |||
@@ -14,12 +14,22 @@ static int crashing_cpu = -1; | |||
14 | static cpumask_t cpus_in_crash = CPU_MASK_NONE; | 14 | static cpumask_t cpus_in_crash = CPU_MASK_NONE; |
15 | 15 | ||
16 | #ifdef CONFIG_SMP | 16 | #ifdef CONFIG_SMP |
17 | static void crash_shutdown_secondary(void *ignore) | 17 | static void crash_shutdown_secondary(void *passed_regs) |
18 | { | 18 | { |
19 | struct pt_regs *regs; | 19 | struct pt_regs *regs = passed_regs; |
20 | int cpu = smp_processor_id(); | 20 | int cpu = smp_processor_id(); |
21 | 21 | ||
22 | regs = task_pt_regs(current); | 22 | /* |
23 | * If we are passed registers, use those. Otherwise get the | ||
24 | * regs from the last interrupt, which should be correct, as | ||
25 | * we are in an interrupt. But if the regs are not there, | ||
26 | * pull them from the top of the stack. They are probably | ||
27 | * wrong, but we need something to keep from crashing again. | ||
28 | */ | ||
29 | if (!regs) | ||
30 | regs = get_irq_regs(); | ||
31 | if (!regs) | ||
32 | regs = task_pt_regs(current); | ||
23 | 33 | ||
24 | if (!cpu_online(cpu)) | 34 | if (!cpu_online(cpu)) |
25 | return; | 35 | return; |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index baa7b6fc0a60..17326a90d53c 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -130,7 +130,7 @@ LEAF(__r4k_wait) | |||
130 | /* end of rollback region (the region size must be power of two) */ | 130 | /* end of rollback region (the region size must be power of two) */ |
131 | 1: | 131 | 1: |
132 | jr ra | 132 | jr ra |
133 | nop | 133 | nop |
134 | .set pop | 134 | .set pop |
135 | END(__r4k_wait) | 135 | END(__r4k_wait) |
136 | 136 | ||
@@ -172,7 +172,7 @@ NESTED(handle_int, PT_SIZE, sp) | |||
172 | mfc0 k0, CP0_EPC | 172 | mfc0 k0, CP0_EPC |
173 | .set noreorder | 173 | .set noreorder |
174 | j k0 | 174 | j k0 |
175 | rfe | 175 | rfe |
176 | #else | 176 | #else |
177 | and k0, ST0_IE | 177 | and k0, ST0_IE |
178 | bnez k0, 1f | 178 | bnez k0, 1f |
@@ -189,7 +189,7 @@ NESTED(handle_int, PT_SIZE, sp) | |||
189 | LONG_L s0, TI_REGS($28) | 189 | LONG_L s0, TI_REGS($28) |
190 | LONG_S sp, TI_REGS($28) | 190 | LONG_S sp, TI_REGS($28) |
191 | PTR_LA ra, ret_from_irq | 191 | PTR_LA ra, ret_from_irq |
192 | PTR_LA v0, plat_irq_dispatch | 192 | PTR_LA v0, plat_irq_dispatch |
193 | jr v0 | 193 | jr v0 |
194 | #ifdef CONFIG_CPU_MICROMIPS | 194 | #ifdef CONFIG_CPU_MICROMIPS |
195 | nop | 195 | nop |
@@ -292,7 +292,7 @@ ejtag_return: | |||
292 | MFC0 k0, CP0_DESAVE | 292 | MFC0 k0, CP0_DESAVE |
293 | .set mips32 | 293 | .set mips32 |
294 | deret | 294 | deret |
295 | .set pop | 295 | .set pop |
296 | END(ejtag_debug_handler) | 296 | END(ejtag_debug_handler) |
297 | 297 | ||
298 | /* | 298 | /* |
@@ -329,10 +329,10 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
329 | * Clear BEV - required for page fault exception handler to work | 329 | * Clear BEV - required for page fault exception handler to work |
330 | */ | 330 | */ |
331 | mfc0 k0, CP0_STATUS | 331 | mfc0 k0, CP0_STATUS |
332 | ori k0, k0, ST0_EXL | 332 | ori k0, k0, ST0_EXL |
333 | li k1, ~(ST0_BEV | ST0_ERL) | 333 | li k1, ~(ST0_BEV | ST0_ERL) |
334 | and k0, k0, k1 | 334 | and k0, k0, k1 |
335 | mtc0 k0, CP0_STATUS | 335 | mtc0 k0, CP0_STATUS |
336 | _ehb | 336 | _ehb |
337 | SAVE_ALL | 337 | SAVE_ALL |
338 | move a0, sp | 338 | move a0, sp |
@@ -396,7 +396,7 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
396 | 396 | ||
397 | .macro __BUILD_count exception | 397 | .macro __BUILD_count exception |
398 | LONG_L t0,exception_count_\exception | 398 | LONG_L t0,exception_count_\exception |
399 | LONG_ADDIU t0, 1 | 399 | LONG_ADDIU t0, 1 |
400 | LONG_S t0,exception_count_\exception | 400 | LONG_S t0,exception_count_\exception |
401 | .comm exception_count\exception, 8, 8 | 401 | .comm exception_count\exception, 8, 8 |
402 | .endm | 402 | .endm |
@@ -455,10 +455,10 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
455 | .set noreorder | 455 | .set noreorder |
456 | /* check if TLB contains a entry for EPC */ | 456 | /* check if TLB contains a entry for EPC */ |
457 | MFC0 k1, CP0_ENTRYHI | 457 | MFC0 k1, CP0_ENTRYHI |
458 | andi k1, 0xff /* ASID_MASK */ | 458 | andi k1, MIPS_ENTRYHI_ASID | MIPS_ENTRYHI_ASIDX |
459 | MFC0 k0, CP0_EPC | 459 | MFC0 k0, CP0_EPC |
460 | PTR_SRL k0, _PAGE_SHIFT + 1 | 460 | PTR_SRL k0, _PAGE_SHIFT + 1 |
461 | PTR_SLL k0, _PAGE_SHIFT + 1 | 461 | PTR_SLL k0, _PAGE_SHIFT + 1 |
462 | or k1, k0 | 462 | or k1, k0 |
463 | MTC0 k1, CP0_ENTRYHI | 463 | MTC0 k1, CP0_ENTRYHI |
464 | mtc0_tlbw_hazard | 464 | mtc0_tlbw_hazard |
@@ -478,27 +478,27 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
478 | /* microMIPS: 0x007d6b3c: rdhwr v1,$29 */ | 478 | /* microMIPS: 0x007d6b3c: rdhwr v1,$29 */ |
479 | MFC0 k1, CP0_EPC | 479 | MFC0 k1, CP0_EPC |
480 | #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS64_R2) | 480 | #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS64_R2) |
481 | and k0, k1, 1 | 481 | and k0, k1, 1 |
482 | beqz k0, 1f | 482 | beqz k0, 1f |
483 | xor k1, k0 | 483 | xor k1, k0 |
484 | lhu k0, (k1) | 484 | lhu k0, (k1) |
485 | lhu k1, 2(k1) | 485 | lhu k1, 2(k1) |
486 | ins k1, k0, 16, 16 | 486 | ins k1, k0, 16, 16 |
487 | lui k0, 0x007d | 487 | lui k0, 0x007d |
488 | b docheck | 488 | b docheck |
489 | ori k0, 0x6b3c | 489 | ori k0, 0x6b3c |
490 | 1: | 490 | 1: |
491 | lui k0, 0x7c03 | 491 | lui k0, 0x7c03 |
492 | lw k1, (k1) | 492 | lw k1, (k1) |
493 | ori k0, 0xe83b | 493 | ori k0, 0xe83b |
494 | #else | 494 | #else |
495 | andi k0, k1, 1 | 495 | andi k0, k1, 1 |
496 | bnez k0, handle_ri | 496 | bnez k0, handle_ri |
497 | lui k0, 0x7c03 | 497 | lui k0, 0x7c03 |
498 | lw k1, (k1) | 498 | lw k1, (k1) |
499 | ori k0, 0xe83b | 499 | ori k0, 0xe83b |
500 | #endif | 500 | #endif |
501 | .set reorder | 501 | .set reorder |
502 | docheck: | 502 | docheck: |
503 | bne k0, k1, handle_ri /* if not ours */ | 503 | bne k0, k1, handle_ri /* if not ours */ |
504 | 504 | ||
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 4e4cc5b9a771..56e8fede3fd8 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <asm/asmmacro.h> | 21 | #include <asm/asmmacro.h> |
22 | #include <asm/irqflags.h> | 22 | #include <asm/irqflags.h> |
23 | #include <asm/regdef.h> | 23 | #include <asm/regdef.h> |
24 | #include <asm/pgtable-bits.h> | ||
25 | #include <asm/mipsregs.h> | 24 | #include <asm/mipsregs.h> |
26 | #include <asm/stackframe.h> | 25 | #include <asm/stackframe.h> |
27 | 26 | ||
@@ -132,7 +131,27 @@ not_found: | |||
132 | set_saved_sp sp, t0, t1 | 131 | set_saved_sp sp, t0, t1 |
133 | PTR_SUBU sp, 4 * SZREG # init stack pointer | 132 | PTR_SUBU sp, 4 * SZREG # init stack pointer |
134 | 133 | ||
134 | #ifdef CONFIG_RELOCATABLE | ||
135 | /* Copy kernel and apply the relocations */ | ||
136 | jal relocate_kernel | ||
137 | |||
138 | /* Repoint the sp into the new kernel image */ | ||
139 | PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE | ||
140 | PTR_ADDU sp, $28 | ||
141 | set_saved_sp sp, t0, t1 | ||
142 | PTR_SUBU sp, 4 * SZREG # init stack pointer | ||
143 | |||
144 | /* | ||
145 | * relocate_kernel returns the entry point either | ||
146 | * in the relocated kernel or the original if for | ||
147 | * some reason relocation failed - jump there now | ||
148 | * with instruction hazard barrier because of the | ||
149 | * newly sync'd icache. | ||
150 | */ | ||
151 | jr.hb v0 | ||
152 | #else | ||
135 | j start_kernel | 153 | j start_kernel |
154 | #endif | ||
136 | END(kernel_entry) | 155 | END(kernel_entry) |
137 | 156 | ||
138 | #ifdef CONFIG_SMP | 157 | #ifdef CONFIG_SMP |
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 46794d64c0bf..60ab4c44d305 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c | |||
@@ -181,6 +181,11 @@ void __init check_wait(void) | |||
181 | case CPU_XLP: | 181 | case CPU_XLP: |
182 | cpu_wait = r4k_wait; | 182 | cpu_wait = r4k_wait; |
183 | break; | 183 | break; |
184 | case CPU_LOONGSON3: | ||
185 | if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON3A_R2) | ||
186 | cpu_wait = r4k_wait; | ||
187 | break; | ||
188 | |||
184 | case CPU_BMIPS5000: | 189 | case CPU_BMIPS5000: |
185 | cpu_wait = r4k_wait_irqoff; | 190 | cpu_wait = r4k_wait_irqoff; |
186 | break; | 191 | break; |
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index 3fff89ae760b..625ee770b1aa 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/inst.h> | 28 | #include <asm/inst.h> |
29 | #include <asm/mips-r2-to-r6-emul.h> | 29 | #include <asm/mips-r2-to-r6-emul.h> |
30 | #include <asm/local.h> | 30 | #include <asm/local.h> |
31 | #include <asm/mipsregs.h> | ||
31 | #include <asm/ptrace.h> | 32 | #include <asm/ptrace.h> |
32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
33 | 34 | ||
@@ -1251,10 +1252,10 @@ fpu_emul: | |||
1251 | " j 10b\n" | 1252 | " j 10b\n" |
1252 | " .previous\n" | 1253 | " .previous\n" |
1253 | " .section __ex_table,\"a\"\n" | 1254 | " .section __ex_table,\"a\"\n" |
1254 | " .word 1b,8b\n" | 1255 | STR(PTR) " 1b,8b\n" |
1255 | " .word 2b,8b\n" | 1256 | STR(PTR) " 2b,8b\n" |
1256 | " .word 3b,8b\n" | 1257 | STR(PTR) " 3b,8b\n" |
1257 | " .word 4b,8b\n" | 1258 | STR(PTR) " 4b,8b\n" |
1258 | " .previous\n" | 1259 | " .previous\n" |
1259 | " .set pop\n" | 1260 | " .set pop\n" |
1260 | : "+&r"(rt), "=&r"(rs), | 1261 | : "+&r"(rt), "=&r"(rs), |
@@ -1326,10 +1327,10 @@ fpu_emul: | |||
1326 | " j 10b\n" | 1327 | " j 10b\n" |
1327 | " .previous\n" | 1328 | " .previous\n" |
1328 | " .section __ex_table,\"a\"\n" | 1329 | " .section __ex_table,\"a\"\n" |
1329 | " .word 1b,8b\n" | 1330 | STR(PTR) " 1b,8b\n" |
1330 | " .word 2b,8b\n" | 1331 | STR(PTR) " 2b,8b\n" |
1331 | " .word 3b,8b\n" | 1332 | STR(PTR) " 3b,8b\n" |
1332 | " .word 4b,8b\n" | 1333 | STR(PTR) " 4b,8b\n" |
1333 | " .previous\n" | 1334 | " .previous\n" |
1334 | " .set pop\n" | 1335 | " .set pop\n" |
1335 | : "+&r"(rt), "=&r"(rs), | 1336 | : "+&r"(rt), "=&r"(rs), |
@@ -1397,10 +1398,10 @@ fpu_emul: | |||
1397 | " j 9b\n" | 1398 | " j 9b\n" |
1398 | " .previous\n" | 1399 | " .previous\n" |
1399 | " .section __ex_table,\"a\"\n" | 1400 | " .section __ex_table,\"a\"\n" |
1400 | " .word 1b,8b\n" | 1401 | STR(PTR) " 1b,8b\n" |
1401 | " .word 2b,8b\n" | 1402 | STR(PTR) " 2b,8b\n" |
1402 | " .word 3b,8b\n" | 1403 | STR(PTR) " 3b,8b\n" |
1403 | " .word 4b,8b\n" | 1404 | STR(PTR) " 4b,8b\n" |
1404 | " .previous\n" | 1405 | " .previous\n" |
1405 | " .set pop\n" | 1406 | " .set pop\n" |
1406 | : "+&r"(rt), "=&r"(rs), | 1407 | : "+&r"(rt), "=&r"(rs), |
@@ -1467,10 +1468,10 @@ fpu_emul: | |||
1467 | " j 9b\n" | 1468 | " j 9b\n" |
1468 | " .previous\n" | 1469 | " .previous\n" |
1469 | " .section __ex_table,\"a\"\n" | 1470 | " .section __ex_table,\"a\"\n" |
1470 | " .word 1b,8b\n" | 1471 | STR(PTR) " 1b,8b\n" |
1471 | " .word 2b,8b\n" | 1472 | STR(PTR) " 2b,8b\n" |
1472 | " .word 3b,8b\n" | 1473 | STR(PTR) " 3b,8b\n" |
1473 | " .word 4b,8b\n" | 1474 | STR(PTR) " 4b,8b\n" |
1474 | " .previous\n" | 1475 | " .previous\n" |
1475 | " .set pop\n" | 1476 | " .set pop\n" |
1476 | : "+&r"(rt), "=&r"(rs), | 1477 | : "+&r"(rt), "=&r"(rs), |
@@ -1582,14 +1583,14 @@ fpu_emul: | |||
1582 | " j 9b\n" | 1583 | " j 9b\n" |
1583 | " .previous\n" | 1584 | " .previous\n" |
1584 | " .section __ex_table,\"a\"\n" | 1585 | " .section __ex_table,\"a\"\n" |
1585 | " .word 1b,8b\n" | 1586 | STR(PTR) " 1b,8b\n" |
1586 | " .word 2b,8b\n" | 1587 | STR(PTR) " 2b,8b\n" |
1587 | " .word 3b,8b\n" | 1588 | STR(PTR) " 3b,8b\n" |
1588 | " .word 4b,8b\n" | 1589 | STR(PTR) " 4b,8b\n" |
1589 | " .word 5b,8b\n" | 1590 | STR(PTR) " 5b,8b\n" |
1590 | " .word 6b,8b\n" | 1591 | STR(PTR) " 6b,8b\n" |
1591 | " .word 7b,8b\n" | 1592 | STR(PTR) " 7b,8b\n" |
1592 | " .word 0b,8b\n" | 1593 | STR(PTR) " 0b,8b\n" |
1593 | " .previous\n" | 1594 | " .previous\n" |
1594 | " .set pop\n" | 1595 | " .set pop\n" |
1595 | : "+&r"(rt), "=&r"(rs), | 1596 | : "+&r"(rt), "=&r"(rs), |
@@ -1701,14 +1702,14 @@ fpu_emul: | |||
1701 | " j 9b\n" | 1702 | " j 9b\n" |
1702 | " .previous\n" | 1703 | " .previous\n" |
1703 | " .section __ex_table,\"a\"\n" | 1704 | " .section __ex_table,\"a\"\n" |
1704 | " .word 1b,8b\n" | 1705 | STR(PTR) " 1b,8b\n" |
1705 | " .word 2b,8b\n" | 1706 | STR(PTR) " 2b,8b\n" |
1706 | " .word 3b,8b\n" | 1707 | STR(PTR) " 3b,8b\n" |
1707 | " .word 4b,8b\n" | 1708 | STR(PTR) " 4b,8b\n" |
1708 | " .word 5b,8b\n" | 1709 | STR(PTR) " 5b,8b\n" |
1709 | " .word 6b,8b\n" | 1710 | STR(PTR) " 6b,8b\n" |
1710 | " .word 7b,8b\n" | 1711 | STR(PTR) " 7b,8b\n" |
1711 | " .word 0b,8b\n" | 1712 | STR(PTR) " 0b,8b\n" |
1712 | " .previous\n" | 1713 | " .previous\n" |
1713 | " .set pop\n" | 1714 | " .set pop\n" |
1714 | : "+&r"(rt), "=&r"(rs), | 1715 | : "+&r"(rt), "=&r"(rs), |
@@ -1820,14 +1821,14 @@ fpu_emul: | |||
1820 | " j 9b\n" | 1821 | " j 9b\n" |
1821 | " .previous\n" | 1822 | " .previous\n" |
1822 | " .section __ex_table,\"a\"\n" | 1823 | " .section __ex_table,\"a\"\n" |
1823 | " .word 1b,8b\n" | 1824 | STR(PTR) " 1b,8b\n" |
1824 | " .word 2b,8b\n" | 1825 | STR(PTR) " 2b,8b\n" |
1825 | " .word 3b,8b\n" | 1826 | STR(PTR) " 3b,8b\n" |
1826 | " .word 4b,8b\n" | 1827 | STR(PTR) " 4b,8b\n" |
1827 | " .word 5b,8b\n" | 1828 | STR(PTR) " 5b,8b\n" |
1828 | " .word 6b,8b\n" | 1829 | STR(PTR) " 6b,8b\n" |
1829 | " .word 7b,8b\n" | 1830 | STR(PTR) " 7b,8b\n" |
1830 | " .word 0b,8b\n" | 1831 | STR(PTR) " 0b,8b\n" |
1831 | " .previous\n" | 1832 | " .previous\n" |
1832 | " .set pop\n" | 1833 | " .set pop\n" |
1833 | : "+&r"(rt), "=&r"(rs), | 1834 | : "+&r"(rt), "=&r"(rs), |
@@ -1938,14 +1939,14 @@ fpu_emul: | |||
1938 | " j 9b\n" | 1939 | " j 9b\n" |
1939 | " .previous\n" | 1940 | " .previous\n" |
1940 | " .section __ex_table,\"a\"\n" | 1941 | " .section __ex_table,\"a\"\n" |
1941 | " .word 1b,8b\n" | 1942 | STR(PTR) " 1b,8b\n" |
1942 | " .word 2b,8b\n" | 1943 | STR(PTR) " 2b,8b\n" |
1943 | " .word 3b,8b\n" | 1944 | STR(PTR) " 3b,8b\n" |
1944 | " .word 4b,8b\n" | 1945 | STR(PTR) " 4b,8b\n" |
1945 | " .word 5b,8b\n" | 1946 | STR(PTR) " 5b,8b\n" |
1946 | " .word 6b,8b\n" | 1947 | STR(PTR) " 6b,8b\n" |
1947 | " .word 7b,8b\n" | 1948 | STR(PTR) " 7b,8b\n" |
1948 | " .word 0b,8b\n" | 1949 | STR(PTR) " 0b,8b\n" |
1949 | " .previous\n" | 1950 | " .previous\n" |
1950 | " .set pop\n" | 1951 | " .set pop\n" |
1951 | : "+&r"(rt), "=&r"(rs), | 1952 | : "+&r"(rt), "=&r"(rs), |
@@ -2000,7 +2001,7 @@ fpu_emul: | |||
2000 | "j 2b\n" | 2001 | "j 2b\n" |
2001 | ".previous\n" | 2002 | ".previous\n" |
2002 | ".section __ex_table,\"a\"\n" | 2003 | ".section __ex_table,\"a\"\n" |
2003 | ".word 1b, 3b\n" | 2004 | STR(PTR) " 1b,3b\n" |
2004 | ".previous\n" | 2005 | ".previous\n" |
2005 | : "=&r"(res), "+&r"(err) | 2006 | : "=&r"(res), "+&r"(err) |
2006 | : "r"(vaddr), "i"(SIGSEGV) | 2007 | : "r"(vaddr), "i"(SIGSEGV) |
@@ -2058,7 +2059,7 @@ fpu_emul: | |||
2058 | "j 2b\n" | 2059 | "j 2b\n" |
2059 | ".previous\n" | 2060 | ".previous\n" |
2060 | ".section __ex_table,\"a\"\n" | 2061 | ".section __ex_table,\"a\"\n" |
2061 | ".word 1b, 3b\n" | 2062 | STR(PTR) " 1b,3b\n" |
2062 | ".previous\n" | 2063 | ".previous\n" |
2063 | : "+&r"(res), "+&r"(err) | 2064 | : "+&r"(res), "+&r"(err) |
2064 | : "r"(vaddr), "i"(SIGSEGV)); | 2065 | : "r"(vaddr), "i"(SIGSEGV)); |
@@ -2119,7 +2120,7 @@ fpu_emul: | |||
2119 | "j 2b\n" | 2120 | "j 2b\n" |
2120 | ".previous\n" | 2121 | ".previous\n" |
2121 | ".section __ex_table,\"a\"\n" | 2122 | ".section __ex_table,\"a\"\n" |
2122 | ".word 1b, 3b\n" | 2123 | STR(PTR) " 1b,3b\n" |
2123 | ".previous\n" | 2124 | ".previous\n" |
2124 | : "=&r"(res), "+&r"(err) | 2125 | : "=&r"(res), "+&r"(err) |
2125 | : "r"(vaddr), "i"(SIGSEGV) | 2126 | : "r"(vaddr), "i"(SIGSEGV) |
@@ -2182,7 +2183,7 @@ fpu_emul: | |||
2182 | "j 2b\n" | 2183 | "j 2b\n" |
2183 | ".previous\n" | 2184 | ".previous\n" |
2184 | ".section __ex_table,\"a\"\n" | 2185 | ".section __ex_table,\"a\"\n" |
2185 | ".word 1b, 3b\n" | 2186 | STR(PTR) " 1b,3b\n" |
2186 | ".previous\n" | 2187 | ".previous\n" |
2187 | : "+&r"(res), "+&r"(err) | 2188 | : "+&r"(res), "+&r"(err) |
2188 | : "r"(vaddr), "i"(SIGSEGV)); | 2189 | : "r"(vaddr), "i"(SIGSEGV)); |
diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c index 9083d63b765c..781168834456 100644 --- a/arch/mips/kernel/module-rela.c +++ b/arch/mips/kernel/module-rela.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Copyright (C) 2001 Rusty Russell. | 16 | * Copyright (C) 2001 Rusty Russell. |
17 | * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) | 17 | * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) |
18 | * Copyright (C) 2005 Thiemo Seufer | 18 | * Copyright (C) 2005 Thiemo Seufer |
19 | * Copyright (C) 2015 Imagination Technologies Ltd. | ||
19 | */ | 20 | */ |
20 | 21 | ||
21 | #include <linux/elf.h> | 22 | #include <linux/elf.h> |
@@ -35,15 +36,13 @@ static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) | |||
35 | static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) | 36 | static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) |
36 | { | 37 | { |
37 | if (v % 4) { | 38 | if (v % 4) { |
38 | pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", | 39 | pr_err("module %s: dangerous R_MIPS_26 RELA relocation\n", |
39 | me->name); | 40 | me->name); |
40 | return -ENOEXEC; | 41 | return -ENOEXEC; |
41 | } | 42 | } |
42 | 43 | ||
43 | if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { | 44 | if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { |
44 | printk(KERN_ERR | 45 | pr_err("module %s: relocation overflow\n", me->name); |
45 | "module %s: relocation overflow\n", | ||
46 | me->name); | ||
47 | return -ENOEXEC; | 46 | return -ENOEXEC; |
48 | } | 47 | } |
49 | 48 | ||
@@ -67,6 +66,48 @@ static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v) | |||
67 | return 0; | 66 | return 0; |
68 | } | 67 | } |
69 | 68 | ||
69 | static int apply_r_mips_pc_rela(struct module *me, u32 *location, Elf_Addr v, | ||
70 | unsigned bits) | ||
71 | { | ||
72 | unsigned long mask = GENMASK(bits - 1, 0); | ||
73 | unsigned long se_bits; | ||
74 | long offset; | ||
75 | |||
76 | if (v % 4) { | ||
77 | pr_err("module %s: dangerous R_MIPS_PC%u RELA relocation\n", | ||
78 | me->name, bits); | ||
79 | return -ENOEXEC; | ||
80 | } | ||
81 | |||
82 | offset = ((long)v - (long)location) >> 2; | ||
83 | |||
84 | /* check the sign bit onwards are identical - ie. we didn't overflow */ | ||
85 | se_bits = (offset & BIT(bits - 1)) ? ~0ul : 0; | ||
86 | if ((offset & ~mask) != (se_bits & ~mask)) { | ||
87 | pr_err("module %s: relocation overflow\n", me->name); | ||
88 | return -ENOEXEC; | ||
89 | } | ||
90 | |||
91 | *location = (*location & ~mask) | (offset & mask); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int apply_r_mips_pc16_rela(struct module *me, u32 *location, Elf_Addr v) | ||
97 | { | ||
98 | return apply_r_mips_pc_rela(me, location, v, 16); | ||
99 | } | ||
100 | |||
101 | static int apply_r_mips_pc21_rela(struct module *me, u32 *location, Elf_Addr v) | ||
102 | { | ||
103 | return apply_r_mips_pc_rela(me, location, v, 21); | ||
104 | } | ||
105 | |||
106 | static int apply_r_mips_pc26_rela(struct module *me, u32 *location, Elf_Addr v) | ||
107 | { | ||
108 | return apply_r_mips_pc_rela(me, location, v, 26); | ||
109 | } | ||
110 | |||
70 | static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v) | 111 | static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v) |
71 | { | 112 | { |
72 | *(Elf_Addr *)location = v; | 113 | *(Elf_Addr *)location = v; |
@@ -99,9 +140,12 @@ static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, | |||
99 | [R_MIPS_26] = apply_r_mips_26_rela, | 140 | [R_MIPS_26] = apply_r_mips_26_rela, |
100 | [R_MIPS_HI16] = apply_r_mips_hi16_rela, | 141 | [R_MIPS_HI16] = apply_r_mips_hi16_rela, |
101 | [R_MIPS_LO16] = apply_r_mips_lo16_rela, | 142 | [R_MIPS_LO16] = apply_r_mips_lo16_rela, |
143 | [R_MIPS_PC16] = apply_r_mips_pc16_rela, | ||
102 | [R_MIPS_64] = apply_r_mips_64_rela, | 144 | [R_MIPS_64] = apply_r_mips_64_rela, |
103 | [R_MIPS_HIGHER] = apply_r_mips_higher_rela, | 145 | [R_MIPS_HIGHER] = apply_r_mips_higher_rela, |
104 | [R_MIPS_HIGHEST] = apply_r_mips_highest_rela | 146 | [R_MIPS_HIGHEST] = apply_r_mips_highest_rela, |
147 | [R_MIPS_PC21_S2] = apply_r_mips_pc21_rela, | ||
148 | [R_MIPS_PC26_S2] = apply_r_mips_pc26_rela, | ||
105 | }; | 149 | }; |
106 | 150 | ||
107 | int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, | 151 | int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, |
@@ -126,11 +170,11 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, | |||
126 | /* This is the symbol it is referring to */ | 170 | /* This is the symbol it is referring to */ |
127 | sym = (Elf_Sym *)sechdrs[symindex].sh_addr | 171 | sym = (Elf_Sym *)sechdrs[symindex].sh_addr |
128 | + ELF_MIPS_R_SYM(rel[i]); | 172 | + ELF_MIPS_R_SYM(rel[i]); |
129 | if (IS_ERR_VALUE(sym->st_value)) { | 173 | if (sym->st_value >= -MAX_ERRNO) { |
130 | /* Ignore unresolved weak symbol */ | 174 | /* Ignore unresolved weak symbol */ |
131 | if (ELF_ST_BIND(sym->st_info) == STB_WEAK) | 175 | if (ELF_ST_BIND(sym->st_info) == STB_WEAK) |
132 | continue; | 176 | continue; |
133 | printk(KERN_WARNING "%s: Unknown symbol %s\n", | 177 | pr_warn("%s: Unknown symbol %s\n", |
134 | me->name, strtab + sym->st_name); | 178 | me->name, strtab + sym->st_name); |
135 | return -ENOENT; | 179 | return -ENOENT; |
136 | } | 180 | } |
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index f9b2936d598d..79850e376ef6 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c | |||
@@ -73,8 +73,7 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { | 75 | if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { |
76 | printk(KERN_ERR | 76 | pr_err("module %s: relocation overflow\n", |
77 | "module %s: relocation overflow\n", | ||
78 | me->name); | 77 | me->name); |
79 | return -ENOEXEC; | 78 | return -ENOEXEC; |
80 | } | 79 | } |
@@ -183,13 +182,62 @@ out_danger: | |||
183 | return -ENOEXEC; | 182 | return -ENOEXEC; |
184 | } | 183 | } |
185 | 184 | ||
185 | static int apply_r_mips_pc_rel(struct module *me, u32 *location, Elf_Addr v, | ||
186 | unsigned bits) | ||
187 | { | ||
188 | unsigned long mask = GENMASK(bits - 1, 0); | ||
189 | unsigned long se_bits; | ||
190 | long offset; | ||
191 | |||
192 | if (v % 4) { | ||
193 | pr_err("module %s: dangerous R_MIPS_PC%u REL relocation\n", | ||
194 | me->name, bits); | ||
195 | return -ENOEXEC; | ||
196 | } | ||
197 | |||
198 | /* retrieve & sign extend implicit addend */ | ||
199 | offset = *location & mask; | ||
200 | offset |= (offset & BIT(bits - 1)) ? ~mask : 0; | ||
201 | |||
202 | offset += ((long)v - (long)location) >> 2; | ||
203 | |||
204 | /* check the sign bit onwards are identical - ie. we didn't overflow */ | ||
205 | se_bits = (offset & BIT(bits - 1)) ? ~0ul : 0; | ||
206 | if ((offset & ~mask) != (se_bits & ~mask)) { | ||
207 | pr_err("module %s: relocation overflow\n", me->name); | ||
208 | return -ENOEXEC; | ||
209 | } | ||
210 | |||
211 | *location = (*location & ~mask) | (offset & mask); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int apply_r_mips_pc16_rel(struct module *me, u32 *location, Elf_Addr v) | ||
217 | { | ||
218 | return apply_r_mips_pc_rel(me, location, v, 16); | ||
219 | } | ||
220 | |||
221 | static int apply_r_mips_pc21_rel(struct module *me, u32 *location, Elf_Addr v) | ||
222 | { | ||
223 | return apply_r_mips_pc_rel(me, location, v, 21); | ||
224 | } | ||
225 | |||
226 | static int apply_r_mips_pc26_rel(struct module *me, u32 *location, Elf_Addr v) | ||
227 | { | ||
228 | return apply_r_mips_pc_rel(me, location, v, 26); | ||
229 | } | ||
230 | |||
186 | static int (*reloc_handlers_rel[]) (struct module *me, u32 *location, | 231 | static int (*reloc_handlers_rel[]) (struct module *me, u32 *location, |
187 | Elf_Addr v) = { | 232 | Elf_Addr v) = { |
188 | [R_MIPS_NONE] = apply_r_mips_none, | 233 | [R_MIPS_NONE] = apply_r_mips_none, |
189 | [R_MIPS_32] = apply_r_mips_32_rel, | 234 | [R_MIPS_32] = apply_r_mips_32_rel, |
190 | [R_MIPS_26] = apply_r_mips_26_rel, | 235 | [R_MIPS_26] = apply_r_mips_26_rel, |
191 | [R_MIPS_HI16] = apply_r_mips_hi16_rel, | 236 | [R_MIPS_HI16] = apply_r_mips_hi16_rel, |
192 | [R_MIPS_LO16] = apply_r_mips_lo16_rel | 237 | [R_MIPS_LO16] = apply_r_mips_lo16_rel, |
238 | [R_MIPS_PC16] = apply_r_mips_pc16_rel, | ||
239 | [R_MIPS_PC21_S2] = apply_r_mips_pc21_rel, | ||
240 | [R_MIPS_PC26_S2] = apply_r_mips_pc26_rel, | ||
193 | }; | 241 | }; |
194 | 242 | ||
195 | int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, | 243 | int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, |
@@ -215,12 +263,12 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, | |||
215 | /* This is the symbol it is referring to */ | 263 | /* This is the symbol it is referring to */ |
216 | sym = (Elf_Sym *)sechdrs[symindex].sh_addr | 264 | sym = (Elf_Sym *)sechdrs[symindex].sh_addr |
217 | + ELF_MIPS_R_SYM(rel[i]); | 265 | + ELF_MIPS_R_SYM(rel[i]); |
218 | if (IS_ERR_VALUE(sym->st_value)) { | 266 | if (sym->st_value >= -MAX_ERRNO) { |
219 | /* Ignore unresolved weak symbol */ | 267 | /* Ignore unresolved weak symbol */ |
220 | if (ELF_ST_BIND(sym->st_info) == STB_WEAK) | 268 | if (ELF_ST_BIND(sym->st_info) == STB_WEAK) |
221 | continue; | 269 | continue; |
222 | printk(KERN_WARNING "%s: Unknown symbol %s\n", | 270 | pr_warn("%s: Unknown symbol %s\n", |
223 | me->name, strtab + sym->st_name); | 271 | me->name, strtab + sym->st_name); |
224 | return -ENOENT; | 272 | return -ENOENT; |
225 | } | 273 | } |
226 | 274 | ||
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 9bc1191b1ab0..d3ba9f4105b5 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -101,8 +101,6 @@ struct mips_pmu { | |||
101 | 101 | ||
102 | static struct mips_pmu mipspmu; | 102 | static struct mips_pmu mipspmu; |
103 | 103 | ||
104 | #define M_CONFIG1_PC (1 << 4) | ||
105 | |||
106 | #define M_PERFCTL_EXL (1 << 0) | 104 | #define M_PERFCTL_EXL (1 << 0) |
107 | #define M_PERFCTL_KERNEL (1 << 1) | 105 | #define M_PERFCTL_KERNEL (1 << 1) |
108 | #define M_PERFCTL_SUPERVISOR (1 << 2) | 106 | #define M_PERFCTL_SUPERVISOR (1 << 2) |
@@ -754,7 +752,7 @@ static void handle_associated_event(struct cpu_hw_events *cpuc, | |||
754 | 752 | ||
755 | static int __n_counters(void) | 753 | static int __n_counters(void) |
756 | { | 754 | { |
757 | if (!(read_c0_config1() & M_CONFIG1_PC)) | 755 | if (!cpu_has_perf) |
758 | return 0; | 756 | return 0; |
759 | if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) | 757 | if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) |
760 | return 1; | 758 | return 1; |
@@ -825,6 +823,16 @@ static const struct mips_perf_event mipsxxcore_event_map2 | |||
825 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T }, | 823 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T }, |
826 | }; | 824 | }; |
827 | 825 | ||
826 | static const struct mips_perf_event i6400_event_map[PERF_COUNT_HW_MAX] = { | ||
827 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD }, | ||
828 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD }, | ||
829 | /* These only count dcache, not icache */ | ||
830 | [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x45, CNTR_EVEN | CNTR_ODD }, | ||
831 | [PERF_COUNT_HW_CACHE_MISSES] = { 0x48, CNTR_EVEN | CNTR_ODD }, | ||
832 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x15, CNTR_EVEN | CNTR_ODD }, | ||
833 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x16, CNTR_EVEN | CNTR_ODD }, | ||
834 | }; | ||
835 | |||
828 | static const struct mips_perf_event loongson3_event_map[PERF_COUNT_HW_MAX] = { | 836 | static const struct mips_perf_event loongson3_event_map[PERF_COUNT_HW_MAX] = { |
829 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN }, | 837 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN }, |
830 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, CNTR_ODD }, | 838 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, CNTR_ODD }, |
@@ -1015,6 +1023,46 @@ static const struct mips_perf_event mipsxxcore_cache_map2 | |||
1015 | }, | 1023 | }, |
1016 | }; | 1024 | }; |
1017 | 1025 | ||
1026 | static const struct mips_perf_event i6400_cache_map | ||
1027 | [PERF_COUNT_HW_CACHE_MAX] | ||
1028 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
1029 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
1030 | [C(L1D)] = { | ||
1031 | [C(OP_READ)] = { | ||
1032 | [C(RESULT_ACCESS)] = { 0x46, CNTR_EVEN | CNTR_ODD }, | ||
1033 | [C(RESULT_MISS)] = { 0x49, CNTR_EVEN | CNTR_ODD }, | ||
1034 | }, | ||
1035 | [C(OP_WRITE)] = { | ||
1036 | [C(RESULT_ACCESS)] = { 0x47, CNTR_EVEN | CNTR_ODD }, | ||
1037 | [C(RESULT_MISS)] = { 0x4a, CNTR_EVEN | CNTR_ODD }, | ||
1038 | }, | ||
1039 | }, | ||
1040 | [C(L1I)] = { | ||
1041 | [C(OP_READ)] = { | ||
1042 | [C(RESULT_ACCESS)] = { 0x84, CNTR_EVEN | CNTR_ODD }, | ||
1043 | [C(RESULT_MISS)] = { 0x85, CNTR_EVEN | CNTR_ODD }, | ||
1044 | }, | ||
1045 | }, | ||
1046 | [C(DTLB)] = { | ||
1047 | /* Can't distinguish read & write */ | ||
1048 | [C(OP_READ)] = { | ||
1049 | [C(RESULT_ACCESS)] = { 0x40, CNTR_EVEN | CNTR_ODD }, | ||
1050 | [C(RESULT_MISS)] = { 0x41, CNTR_EVEN | CNTR_ODD }, | ||
1051 | }, | ||
1052 | [C(OP_WRITE)] = { | ||
1053 | [C(RESULT_ACCESS)] = { 0x40, CNTR_EVEN | CNTR_ODD }, | ||
1054 | [C(RESULT_MISS)] = { 0x41, CNTR_EVEN | CNTR_ODD }, | ||
1055 | }, | ||
1056 | }, | ||
1057 | [C(BPU)] = { | ||
1058 | /* Conditional branches / mispredicted */ | ||
1059 | [C(OP_READ)] = { | ||
1060 | [C(RESULT_ACCESS)] = { 0x15, CNTR_EVEN | CNTR_ODD }, | ||
1061 | [C(RESULT_MISS)] = { 0x16, CNTR_EVEN | CNTR_ODD }, | ||
1062 | }, | ||
1063 | }, | ||
1064 | }; | ||
1065 | |||
1018 | static const struct mips_perf_event loongson3_cache_map | 1066 | static const struct mips_perf_event loongson3_cache_map |
1019 | [PERF_COUNT_HW_CACHE_MAX] | 1067 | [PERF_COUNT_HW_CACHE_MAX] |
1020 | [PERF_COUNT_HW_CACHE_OP_MAX] | 1068 | [PERF_COUNT_HW_CACHE_OP_MAX] |
@@ -1556,6 +1604,7 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) | |||
1556 | #endif | 1604 | #endif |
1557 | break; | 1605 | break; |
1558 | case CPU_P5600: | 1606 | case CPU_P5600: |
1607 | case CPU_P6600: | ||
1559 | case CPU_I6400: | 1608 | case CPU_I6400: |
1560 | /* 8-bit event numbers */ | 1609 | /* 8-bit event numbers */ |
1561 | raw_id = config & 0x1ff; | 1610 | raw_id = config & 0x1ff; |
@@ -1718,11 +1767,16 @@ init_hw_perf_events(void) | |||
1718 | mipspmu.general_event_map = &mipsxxcore_event_map2; | 1767 | mipspmu.general_event_map = &mipsxxcore_event_map2; |
1719 | mipspmu.cache_event_map = &mipsxxcore_cache_map2; | 1768 | mipspmu.cache_event_map = &mipsxxcore_cache_map2; |
1720 | break; | 1769 | break; |
1721 | case CPU_I6400: | 1770 | case CPU_P6600: |
1722 | mipspmu.name = "mips/I6400"; | 1771 | mipspmu.name = "mips/P6600"; |
1723 | mipspmu.general_event_map = &mipsxxcore_event_map2; | 1772 | mipspmu.general_event_map = &mipsxxcore_event_map2; |
1724 | mipspmu.cache_event_map = &mipsxxcore_cache_map2; | 1773 | mipspmu.cache_event_map = &mipsxxcore_cache_map2; |
1725 | break; | 1774 | break; |
1775 | case CPU_I6400: | ||
1776 | mipspmu.name = "mips/I6400"; | ||
1777 | mipspmu.general_event_map = &i6400_event_map; | ||
1778 | mipspmu.cache_event_map = &i6400_cache_map; | ||
1779 | break; | ||
1726 | case CPU_1004K: | 1780 | case CPU_1004K: |
1727 | mipspmu.name = "mips/1004K"; | 1781 | mipspmu.name = "mips/1004K"; |
1728 | mipspmu.general_event_map = &mipsxxcore_event_map; | 1782 | mipspmu.general_event_map = &mipsxxcore_event_map; |
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index fa3f9ebad8f4..adda3ffb9b78 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c | |||
@@ -224,11 +224,18 @@ static void __init cps_gen_cache_routine(u32 **pp, struct uasm_label **pl, | |||
224 | uasm_build_label(pl, *pp, lbl); | 224 | uasm_build_label(pl, *pp, lbl); |
225 | 225 | ||
226 | /* Generate the cache ops */ | 226 | /* Generate the cache ops */ |
227 | for (i = 0; i < unroll_lines; i++) | 227 | for (i = 0; i < unroll_lines; i++) { |
228 | uasm_i_cache(pp, op, i * cache->linesz, t0); | 228 | if (cpu_has_mips_r6) { |
229 | uasm_i_cache(pp, op, 0, t0); | ||
230 | uasm_i_addiu(pp, t0, t0, cache->linesz); | ||
231 | } else { | ||
232 | uasm_i_cache(pp, op, i * cache->linesz, t0); | ||
233 | } | ||
234 | } | ||
229 | 235 | ||
230 | /* Update the base address */ | 236 | if (!cpu_has_mips_r6) |
231 | uasm_i_addiu(pp, t0, t0, unroll_lines * cache->linesz); | 237 | /* Update the base address */ |
238 | uasm_i_addiu(pp, t0, t0, unroll_lines * cache->linesz); | ||
232 | 239 | ||
233 | /* Loop if we haven't reached the end address yet */ | 240 | /* Loop if we haven't reached the end address yet */ |
234 | uasm_il_bne(pp, pr, t0, t1, lbl); | 241 | uasm_il_bne(pp, pr, t0, t1, lbl); |
diff --git a/arch/mips/kernel/pm.c b/arch/mips/kernel/pm.c index fefdf39d3df3..dc814892133c 100644 --- a/arch/mips/kernel/pm.c +++ b/arch/mips/kernel/pm.c | |||
@@ -56,7 +56,7 @@ static void mips_cpu_restore(void) | |||
56 | write_c0_userlocal(current_thread_info()->tp_value); | 56 | write_c0_userlocal(current_thread_info()->tp_value); |
57 | 57 | ||
58 | /* Restore watch registers */ | 58 | /* Restore watch registers */ |
59 | __restore_watch(); | 59 | __restore_watch(current); |
60 | } | 60 | } |
61 | 61 | ||
62 | /** | 62 | /** |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 298b2b773d12..97dc01b03631 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -114,6 +114,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
114 | if (cpu_has_smartmips) seq_printf(m, "%s", " smartmips"); | 114 | if (cpu_has_smartmips) seq_printf(m, "%s", " smartmips"); |
115 | if (cpu_has_dsp) seq_printf(m, "%s", " dsp"); | 115 | if (cpu_has_dsp) seq_printf(m, "%s", " dsp"); |
116 | if (cpu_has_dsp2) seq_printf(m, "%s", " dsp2"); | 116 | if (cpu_has_dsp2) seq_printf(m, "%s", " dsp2"); |
117 | if (cpu_has_dsp3) seq_printf(m, "%s", " dsp3"); | ||
117 | if (cpu_has_mipsmt) seq_printf(m, "%s", " mt"); | 118 | if (cpu_has_mipsmt) seq_printf(m, "%s", " mt"); |
118 | if (cpu_has_mmips) seq_printf(m, "%s", " micromips"); | 119 | if (cpu_has_mmips) seq_printf(m, "%s", " micromips"); |
119 | if (cpu_has_vz) seq_printf(m, "%s", " vz"); | 120 | if (cpu_has_vz) seq_printf(m, "%s", " vz"); |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 92880cee449e..a6b3dc54260a 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -77,10 +77,6 @@ void exit_thread(void) | |||
77 | { | 77 | { |
78 | } | 78 | } |
79 | 79 | ||
80 | void flush_thread(void) | ||
81 | { | ||
82 | } | ||
83 | |||
84 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | 80 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) |
85 | { | 81 | { |
86 | /* | 82 | /* |
@@ -455,7 +451,7 @@ unsigned long notrace unwind_stack_by_address(unsigned long stack_page, | |||
455 | *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { | 451 | *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { |
456 | regs = (struct pt_regs *)*sp; | 452 | regs = (struct pt_regs *)*sp; |
457 | pc = regs->cp0_epc; | 453 | pc = regs->cp0_epc; |
458 | if (__kernel_text_address(pc)) { | 454 | if (!user_mode(regs) && __kernel_text_address(pc)) { |
459 | *sp = regs->regs[29]; | 455 | *sp = regs->regs[29]; |
460 | *ra = regs->regs[31]; | 456 | *ra = regs->regs[31]; |
461 | return pc; | 457 | return pc; |
@@ -580,11 +576,19 @@ int mips_get_process_fp_mode(struct task_struct *task) | |||
580 | return value; | 576 | return value; |
581 | } | 577 | } |
582 | 578 | ||
579 | static void prepare_for_fp_mode_switch(void *info) | ||
580 | { | ||
581 | struct mm_struct *mm = info; | ||
582 | |||
583 | if (current->mm == mm) | ||
584 | lose_fpu(1); | ||
585 | } | ||
586 | |||
583 | int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) | 587 | int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) |
584 | { | 588 | { |
585 | const unsigned int known_bits = PR_FP_MODE_FR | PR_FP_MODE_FRE; | 589 | const unsigned int known_bits = PR_FP_MODE_FR | PR_FP_MODE_FRE; |
586 | unsigned long switch_count; | ||
587 | struct task_struct *t; | 590 | struct task_struct *t; |
591 | int max_users; | ||
588 | 592 | ||
589 | /* Check the value is valid */ | 593 | /* Check the value is valid */ |
590 | if (value & ~known_bits) | 594 | if (value & ~known_bits) |
@@ -601,6 +605,9 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) | |||
601 | if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6) | 605 | if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6) |
602 | return -EOPNOTSUPP; | 606 | return -EOPNOTSUPP; |
603 | 607 | ||
608 | /* Proceed with the mode switch */ | ||
609 | preempt_disable(); | ||
610 | |||
604 | /* Save FP & vector context, then disable FPU & MSA */ | 611 | /* Save FP & vector context, then disable FPU & MSA */ |
605 | if (task->signal == current->signal) | 612 | if (task->signal == current->signal) |
606 | lose_fpu(1); | 613 | lose_fpu(1); |
@@ -610,31 +617,17 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) | |||
610 | smp_mb__after_atomic(); | 617 | smp_mb__after_atomic(); |
611 | 618 | ||
612 | /* | 619 | /* |
613 | * If there are multiple online CPUs then wait until all threads whose | 620 | * If there are multiple online CPUs then force any which are running |
614 | * FP mode is about to change have been context switched. This approach | 621 | * threads in this process to lose their FPU context, which they can't |
615 | * allows us to only worry about whether an FP mode switch is in | 622 | * regain until fp_mode_switching is cleared later. |
616 | * progress when FP is first used in a tasks time slice. Pretty much all | ||
617 | * of the mode switch overhead can thus be confined to cases where mode | ||
618 | * switches are actually occurring. That is, to here. However for the | ||
619 | * thread performing the mode switch it may take a while... | ||
620 | */ | 623 | */ |
621 | if (num_online_cpus() > 1) { | 624 | if (num_online_cpus() > 1) { |
622 | spin_lock_irq(&task->sighand->siglock); | 625 | /* No need to send an IPI for the local CPU */ |
623 | 626 | max_users = (task->mm == current->mm) ? 1 : 0; | |
624 | for_each_thread(task, t) { | ||
625 | if (t == current) | ||
626 | continue; | ||
627 | |||
628 | switch_count = t->nvcsw + t->nivcsw; | ||
629 | 627 | ||
630 | do { | 628 | if (atomic_read(¤t->mm->mm_users) > max_users) |
631 | spin_unlock_irq(&task->sighand->siglock); | 629 | smp_call_function(prepare_for_fp_mode_switch, |
632 | cond_resched(); | 630 | (void *)current->mm, 1); |
633 | spin_lock_irq(&task->sighand->siglock); | ||
634 | } while ((t->nvcsw + t->nivcsw) == switch_count); | ||
635 | } | ||
636 | |||
637 | spin_unlock_irq(&task->sighand->siglock); | ||
638 | } | 631 | } |
639 | 632 | ||
640 | /* | 633 | /* |
@@ -659,6 +652,7 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) | |||
659 | 652 | ||
660 | /* Allow threads to use FP again */ | 653 | /* Allow threads to use FP again */ |
661 | atomic_set(&task->mm->context.fp_mode_switching, 0); | 654 | atomic_set(&task->mm->context.fp_mode_switching, 0); |
655 | preempt_enable(); | ||
662 | 656 | ||
663 | return 0; | 657 | return 0; |
664 | } | 658 | } |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index a5279b2f3198..0dcf69194473 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -57,8 +57,7 @@ static void init_fp_ctx(struct task_struct *target) | |||
57 | /* Begin with data registers set to all 1s... */ | 57 | /* Begin with data registers set to all 1s... */ |
58 | memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr)); | 58 | memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr)); |
59 | 59 | ||
60 | /* ...and FCSR zeroed */ | 60 | /* FCSR has been preset by `mips_set_personality_nan'. */ |
61 | target->thread.fpu.fcr31 = 0; | ||
62 | 61 | ||
63 | /* | 62 | /* |
64 | * Record that the target has "used" math, such that the context | 63 | * Record that the target has "used" math, such that the context |
@@ -80,6 +79,22 @@ void ptrace_disable(struct task_struct *child) | |||
80 | } | 79 | } |
81 | 80 | ||
82 | /* | 81 | /* |
82 | * Poke at FCSR according to its mask. Don't set the cause bits as | ||
83 | * this is currently not handled correctly in FP context restoration | ||
84 | * and will cause an oops if a corresponding enable bit is set. | ||
85 | */ | ||
86 | static void ptrace_setfcr31(struct task_struct *child, u32 value) | ||
87 | { | ||
88 | u32 fcr31; | ||
89 | u32 mask; | ||
90 | |||
91 | value &= ~FPU_CSR_ALL_X; | ||
92 | fcr31 = child->thread.fpu.fcr31; | ||
93 | mask = boot_cpu_data.fpu_msk31; | ||
94 | child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask); | ||
95 | } | ||
96 | |||
97 | /* | ||
83 | * Read a general register set. We always use the 64-bit format, even | 98 | * Read a general register set. We always use the 64-bit format, even |
84 | * for 32-bit kernels and for 32-bit processes on a 64-bit kernel. | 99 | * for 32-bit kernels and for 32-bit processes on a 64-bit kernel. |
85 | * Registers are sign extended to fill the available space. | 100 | * Registers are sign extended to fill the available space. |
@@ -159,9 +174,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) | |||
159 | { | 174 | { |
160 | union fpureg *fregs; | 175 | union fpureg *fregs; |
161 | u64 fpr_val; | 176 | u64 fpr_val; |
162 | u32 fcr31; | ||
163 | u32 value; | 177 | u32 value; |
164 | u32 mask; | ||
165 | int i; | 178 | int i; |
166 | 179 | ||
167 | if (!access_ok(VERIFY_READ, data, 33 * 8)) | 180 | if (!access_ok(VERIFY_READ, data, 33 * 8)) |
@@ -176,9 +189,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) | |||
176 | } | 189 | } |
177 | 190 | ||
178 | __get_user(value, data + 64); | 191 | __get_user(value, data + 64); |
179 | fcr31 = child->thread.fpu.fcr31; | 192 | ptrace_setfcr31(child, value); |
180 | mask = boot_cpu_data.fpu_msk31; | ||
181 | child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask); | ||
182 | 193 | ||
183 | /* FIR may not be written. */ | 194 | /* FIR may not be written. */ |
184 | 195 | ||
@@ -210,7 +221,8 @@ int ptrace_get_watch_regs(struct task_struct *child, | |||
210 | for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { | 221 | for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { |
211 | __put_user(child->thread.watch.mips3264.watchlo[i], | 222 | __put_user(child->thread.watch.mips3264.watchlo[i], |
212 | &addr->WATCH_STYLE.watchlo[i]); | 223 | &addr->WATCH_STYLE.watchlo[i]); |
213 | __put_user(child->thread.watch.mips3264.watchhi[i] & 0xfff, | 224 | __put_user(child->thread.watch.mips3264.watchhi[i] & |
225 | (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW), | ||
214 | &addr->WATCH_STYLE.watchhi[i]); | 226 | &addr->WATCH_STYLE.watchhi[i]); |
215 | __put_user(boot_cpu_data.watch_reg_masks[i], | 227 | __put_user(boot_cpu_data.watch_reg_masks[i], |
216 | &addr->WATCH_STYLE.watch_masks[i]); | 228 | &addr->WATCH_STYLE.watch_masks[i]); |
@@ -252,12 +264,12 @@ int ptrace_set_watch_regs(struct task_struct *child, | |||
252 | } | 264 | } |
253 | #endif | 265 | #endif |
254 | __get_user(ht[i], &addr->WATCH_STYLE.watchhi[i]); | 266 | __get_user(ht[i], &addr->WATCH_STYLE.watchhi[i]); |
255 | if (ht[i] & ~0xff8) | 267 | if (ht[i] & ~MIPS_WATCHHI_MASK) |
256 | return -EINVAL; | 268 | return -EINVAL; |
257 | } | 269 | } |
258 | /* Install them. */ | 270 | /* Install them. */ |
259 | for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { | 271 | for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { |
260 | if (lt[i] & 7) | 272 | if (lt[i] & MIPS_WATCHLO_IRW) |
261 | watch_active = 1; | 273 | watch_active = 1; |
262 | child->thread.watch.mips3264.watchlo[i] = lt[i]; | 274 | child->thread.watch.mips3264.watchlo[i] = lt[i]; |
263 | /* Set the G bit. */ | 275 | /* Set the G bit. */ |
@@ -805,7 +817,7 @@ long arch_ptrace(struct task_struct *child, long request, | |||
805 | break; | 817 | break; |
806 | #endif | 818 | #endif |
807 | case FPC_CSR: | 819 | case FPC_CSR: |
808 | child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X; | 820 | ptrace_setfcr31(child, data); |
809 | break; | 821 | break; |
810 | case DSP_BASE ... DSP_BASE + 5: { | 822 | case DSP_BASE ... DSP_BASE + 5: { |
811 | dspreg_t *dregs; | 823 | dspreg_t *dregs; |
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 17732f876eff..56d86b09c917 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S | |||
@@ -244,17 +244,17 @@ LEAF(\name) | |||
244 | .set push | 244 | .set push |
245 | .set noat | 245 | .set noat |
246 | #ifdef CONFIG_64BIT | 246 | #ifdef CONFIG_64BIT |
247 | copy_u_d \wr, 1 | 247 | copy_s_d \wr, 1 |
248 | EX sd $1, \off(\base) | 248 | EX sd $1, \off(\base) |
249 | #elif defined(CONFIG_CPU_LITTLE_ENDIAN) | 249 | #elif defined(CONFIG_CPU_LITTLE_ENDIAN) |
250 | copy_u_w \wr, 2 | 250 | copy_s_w \wr, 2 |
251 | EX sw $1, \off(\base) | 251 | EX sw $1, \off(\base) |
252 | copy_u_w \wr, 3 | 252 | copy_s_w \wr, 3 |
253 | EX sw $1, (\off+4)(\base) | 253 | EX sw $1, (\off+4)(\base) |
254 | #else /* CONFIG_CPU_BIG_ENDIAN */ | 254 | #else /* CONFIG_CPU_BIG_ENDIAN */ |
255 | copy_u_w \wr, 2 | 255 | copy_s_w \wr, 2 |
256 | EX sw $1, (\off+4)(\base) | 256 | EX sw $1, (\off+4)(\base) |
257 | copy_u_w \wr, 3 | 257 | copy_s_w \wr, 3 |
258 | EX sw $1, \off(\base) | 258 | EX sw $1, \off(\base) |
259 | #endif | 259 | #endif |
260 | .set pop | 260 | .set pop |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 92cd0516ecf5..2f0a3b223c97 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <asm/fpregdef.h> | 15 | #include <asm/fpregdef.h> |
16 | #include <asm/mipsregs.h> | 16 | #include <asm/mipsregs.h> |
17 | #include <asm/asm-offsets.h> | 17 | #include <asm/asm-offsets.h> |
18 | #include <asm/pgtable-bits.h> | ||
19 | #include <asm/regdef.h> | 18 | #include <asm/regdef.h> |
20 | #include <asm/stackframe.h> | 19 | #include <asm/stackframe.h> |
21 | #include <asm/thread_info.h> | 20 | #include <asm/thread_info.h> |
diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c new file mode 100644 index 000000000000..ca1cc30c0891 --- /dev/null +++ b/arch/mips/kernel/relocate.c | |||
@@ -0,0 +1,386 @@ | |||
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 | * Support for Kernel relocation at boot time | ||
7 | * | ||
8 | * Copyright (C) 2015, Imagination Technologies Ltd. | ||
9 | * Authors: Matt Redfearn (matt.redfearn@imgtec.com) | ||
10 | */ | ||
11 | #include <asm/bootinfo.h> | ||
12 | #include <asm/cacheflush.h> | ||
13 | #include <asm/fw/fw.h> | ||
14 | #include <asm/sections.h> | ||
15 | #include <asm/setup.h> | ||
16 | #include <asm/timex.h> | ||
17 | #include <linux/elf.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/libfdt.h> | ||
20 | #include <linux/of_fdt.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/start_kernel.h> | ||
23 | #include <linux/string.h> | ||
24 | #include <linux/printk.h> | ||
25 | |||
26 | #define RELOCATED(x) ((void *)((long)x + offset)) | ||
27 | |||
28 | extern u32 _relocation_start[]; /* End kernel image / start relocation table */ | ||
29 | extern u32 _relocation_end[]; /* End relocation table */ | ||
30 | |||
31 | extern long __start___ex_table; /* Start exception table */ | ||
32 | extern long __stop___ex_table; /* End exception table */ | ||
33 | |||
34 | static inline u32 __init get_synci_step(void) | ||
35 | { | ||
36 | u32 res; | ||
37 | |||
38 | __asm__("rdhwr %0, $1" : "=r" (res)); | ||
39 | |||
40 | return res; | ||
41 | } | ||
42 | |||
43 | static void __init sync_icache(void *kbase, unsigned long kernel_length) | ||
44 | { | ||
45 | void *kend = kbase + kernel_length; | ||
46 | u32 step = get_synci_step(); | ||
47 | |||
48 | do { | ||
49 | __asm__ __volatile__( | ||
50 | "synci 0(%0)" | ||
51 | : /* no output */ | ||
52 | : "r" (kbase)); | ||
53 | |||
54 | kbase += step; | ||
55 | } while (kbase < kend); | ||
56 | |||
57 | /* Completion barrier */ | ||
58 | __sync(); | ||
59 | } | ||
60 | |||
61 | static int __init apply_r_mips_64_rel(u32 *loc_orig, u32 *loc_new, long offset) | ||
62 | { | ||
63 | *(u64 *)loc_new += offset; | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static int __init apply_r_mips_32_rel(u32 *loc_orig, u32 *loc_new, long offset) | ||
69 | { | ||
70 | *loc_new += offset; | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int __init apply_r_mips_26_rel(u32 *loc_orig, u32 *loc_new, long offset) | ||
76 | { | ||
77 | unsigned long target_addr = (*loc_orig) & 0x03ffffff; | ||
78 | |||
79 | if (offset % 4) { | ||
80 | pr_err("Dangerous R_MIPS_26 REL relocation\n"); | ||
81 | return -ENOEXEC; | ||
82 | } | ||
83 | |||
84 | /* Original target address */ | ||
85 | target_addr <<= 2; | ||
86 | target_addr += (unsigned long)loc_orig & ~0x03ffffff; | ||
87 | |||
88 | /* Get the new target address */ | ||
89 | target_addr += offset; | ||
90 | |||
91 | if ((target_addr & 0xf0000000) != ((unsigned long)loc_new & 0xf0000000)) { | ||
92 | pr_err("R_MIPS_26 REL relocation overflow\n"); | ||
93 | return -ENOEXEC; | ||
94 | } | ||
95 | |||
96 | target_addr -= (unsigned long)loc_new & ~0x03ffffff; | ||
97 | target_addr >>= 2; | ||
98 | |||
99 | *loc_new = (*loc_new & ~0x03ffffff) | (target_addr & 0x03ffffff); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | |||
105 | static int __init apply_r_mips_hi16_rel(u32 *loc_orig, u32 *loc_new, long offset) | ||
106 | { | ||
107 | unsigned long insn = *loc_orig; | ||
108 | unsigned long target = (insn & 0xffff) << 16; /* high 16bits of target */ | ||
109 | |||
110 | target += offset; | ||
111 | |||
112 | *loc_new = (insn & ~0xffff) | ((target >> 16) & 0xffff); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int (*reloc_handlers_rel[]) (u32 *, u32 *, long) __initdata = { | ||
117 | [R_MIPS_64] = apply_r_mips_64_rel, | ||
118 | [R_MIPS_32] = apply_r_mips_32_rel, | ||
119 | [R_MIPS_26] = apply_r_mips_26_rel, | ||
120 | [R_MIPS_HI16] = apply_r_mips_hi16_rel, | ||
121 | }; | ||
122 | |||
123 | int __init do_relocations(void *kbase_old, void *kbase_new, long offset) | ||
124 | { | ||
125 | u32 *r; | ||
126 | u32 *loc_orig; | ||
127 | u32 *loc_new; | ||
128 | int type; | ||
129 | int res; | ||
130 | |||
131 | for (r = _relocation_start; r < _relocation_end; r++) { | ||
132 | /* Sentinel for last relocation */ | ||
133 | if (*r == 0) | ||
134 | break; | ||
135 | |||
136 | type = (*r >> 24) & 0xff; | ||
137 | loc_orig = (void *)(kbase_old + ((*r & 0x00ffffff) << 2)); | ||
138 | loc_new = RELOCATED(loc_orig); | ||
139 | |||
140 | if (reloc_handlers_rel[type] == NULL) { | ||
141 | /* Unsupported relocation */ | ||
142 | pr_err("Unhandled relocation type %d at 0x%pK\n", | ||
143 | type, loc_orig); | ||
144 | return -ENOEXEC; | ||
145 | } | ||
146 | |||
147 | res = reloc_handlers_rel[type](loc_orig, loc_new, offset); | ||
148 | if (res) | ||
149 | return res; | ||
150 | } | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * The exception table is filled in by the relocs tool after vmlinux is linked. | ||
157 | * It must be relocated separately since there will not be any relocation | ||
158 | * information for it filled in by the linker. | ||
159 | */ | ||
160 | static int __init relocate_exception_table(long offset) | ||
161 | { | ||
162 | unsigned long *etable_start, *etable_end, *e; | ||
163 | |||
164 | etable_start = RELOCATED(&__start___ex_table); | ||
165 | etable_end = RELOCATED(&__stop___ex_table); | ||
166 | |||
167 | for (e = etable_start; e < etable_end; e++) | ||
168 | *e += offset; | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | #ifdef CONFIG_RANDOMIZE_BASE | ||
174 | |||
175 | static inline __init unsigned long rotate_xor(unsigned long hash, | ||
176 | const void *area, size_t size) | ||
177 | { | ||
178 | size_t i; | ||
179 | unsigned long *ptr = (unsigned long *)area; | ||
180 | |||
181 | for (i = 0; i < size / sizeof(hash); i++) { | ||
182 | /* Rotate by odd number of bits and XOR. */ | ||
183 | hash = (hash << ((sizeof(hash) * 8) - 7)) | (hash >> 7); | ||
184 | hash ^= ptr[i]; | ||
185 | } | ||
186 | |||
187 | return hash; | ||
188 | } | ||
189 | |||
190 | static inline __init unsigned long get_random_boot(void) | ||
191 | { | ||
192 | unsigned long entropy = random_get_entropy(); | ||
193 | unsigned long hash = 0; | ||
194 | |||
195 | /* Attempt to create a simple but unpredictable starting entropy. */ | ||
196 | hash = rotate_xor(hash, linux_banner, strlen(linux_banner)); | ||
197 | |||
198 | /* Add in any runtime entropy we can get */ | ||
199 | hash = rotate_xor(hash, &entropy, sizeof(entropy)); | ||
200 | |||
201 | #if defined(CONFIG_USE_OF) | ||
202 | /* Get any additional entropy passed in device tree */ | ||
203 | { | ||
204 | int node, len; | ||
205 | u64 *prop; | ||
206 | |||
207 | node = fdt_path_offset(initial_boot_params, "/chosen"); | ||
208 | if (node >= 0) { | ||
209 | prop = fdt_getprop_w(initial_boot_params, node, | ||
210 | "kaslr-seed", &len); | ||
211 | if (prop && (len == sizeof(u64))) | ||
212 | hash = rotate_xor(hash, prop, sizeof(*prop)); | ||
213 | } | ||
214 | } | ||
215 | #endif /* CONFIG_USE_OF */ | ||
216 | |||
217 | return hash; | ||
218 | } | ||
219 | |||
220 | static inline __init bool kaslr_disabled(void) | ||
221 | { | ||
222 | char *str; | ||
223 | |||
224 | #if defined(CONFIG_CMDLINE_BOOL) | ||
225 | const char *builtin_cmdline = CONFIG_CMDLINE; | ||
226 | |||
227 | str = strstr(builtin_cmdline, "nokaslr"); | ||
228 | if (str == builtin_cmdline || | ||
229 | (str > builtin_cmdline && *(str - 1) == ' ')) | ||
230 | return true; | ||
231 | #endif | ||
232 | str = strstr(arcs_cmdline, "nokaslr"); | ||
233 | if (str == arcs_cmdline || (str > arcs_cmdline && *(str - 1) == ' ')) | ||
234 | return true; | ||
235 | |||
236 | return false; | ||
237 | } | ||
238 | |||
239 | static inline void __init *determine_relocation_address(void) | ||
240 | { | ||
241 | /* Choose a new address for the kernel */ | ||
242 | unsigned long kernel_length; | ||
243 | void *dest = &_text; | ||
244 | unsigned long offset; | ||
245 | |||
246 | if (kaslr_disabled()) | ||
247 | return dest; | ||
248 | |||
249 | kernel_length = (long)_end - (long)(&_text); | ||
250 | |||
251 | offset = get_random_boot() << 16; | ||
252 | offset &= (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1); | ||
253 | if (offset < kernel_length) | ||
254 | offset += ALIGN(kernel_length, 0xffff); | ||
255 | |||
256 | return RELOCATED(dest); | ||
257 | } | ||
258 | |||
259 | #else | ||
260 | |||
261 | static inline void __init *determine_relocation_address(void) | ||
262 | { | ||
263 | /* | ||
264 | * Choose a new address for the kernel | ||
265 | * For now we'll hard code the destination | ||
266 | */ | ||
267 | return (void *)0xffffffff81000000; | ||
268 | } | ||
269 | |||
270 | #endif | ||
271 | |||
272 | static inline int __init relocation_addr_valid(void *loc_new) | ||
273 | { | ||
274 | if ((unsigned long)loc_new & 0x0000ffff) { | ||
275 | /* Inappropriately aligned new location */ | ||
276 | return 0; | ||
277 | } | ||
278 | if ((unsigned long)loc_new < (unsigned long)&_end) { | ||
279 | /* New location overlaps original kernel */ | ||
280 | return 0; | ||
281 | } | ||
282 | return 1; | ||
283 | } | ||
284 | |||
285 | void *__init relocate_kernel(void) | ||
286 | { | ||
287 | void *loc_new; | ||
288 | unsigned long kernel_length; | ||
289 | unsigned long bss_length; | ||
290 | long offset = 0; | ||
291 | int res = 1; | ||
292 | /* Default to original kernel entry point */ | ||
293 | void *kernel_entry = start_kernel; | ||
294 | |||
295 | /* Get the command line */ | ||
296 | fw_init_cmdline(); | ||
297 | #if defined(CONFIG_USE_OF) | ||
298 | /* Deal with the device tree */ | ||
299 | early_init_dt_scan(plat_get_fdt()); | ||
300 | if (boot_command_line[0]) { | ||
301 | /* Boot command line was passed in device tree */ | ||
302 | strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | ||
303 | } | ||
304 | #endif /* CONFIG_USE_OF */ | ||
305 | |||
306 | kernel_length = (long)(&_relocation_start) - (long)(&_text); | ||
307 | bss_length = (long)&__bss_stop - (long)&__bss_start; | ||
308 | |||
309 | loc_new = determine_relocation_address(); | ||
310 | |||
311 | /* Sanity check relocation address */ | ||
312 | if (relocation_addr_valid(loc_new)) | ||
313 | offset = (unsigned long)loc_new - (unsigned long)(&_text); | ||
314 | |||
315 | /* Reset the command line now so we don't end up with a duplicate */ | ||
316 | arcs_cmdline[0] = '\0'; | ||
317 | |||
318 | if (offset) { | ||
319 | /* Copy the kernel to it's new location */ | ||
320 | memcpy(loc_new, &_text, kernel_length); | ||
321 | |||
322 | /* Perform relocations on the new kernel */ | ||
323 | res = do_relocations(&_text, loc_new, offset); | ||
324 | if (res < 0) | ||
325 | goto out; | ||
326 | |||
327 | /* Sync the caches ready for execution of new kernel */ | ||
328 | sync_icache(loc_new, kernel_length); | ||
329 | |||
330 | res = relocate_exception_table(offset); | ||
331 | if (res < 0) | ||
332 | goto out; | ||
333 | |||
334 | /* | ||
335 | * The original .bss has already been cleared, and | ||
336 | * some variables such as command line parameters | ||
337 | * stored to it so make a copy in the new location. | ||
338 | */ | ||
339 | memcpy(RELOCATED(&__bss_start), &__bss_start, bss_length); | ||
340 | |||
341 | /* The current thread is now within the relocated image */ | ||
342 | __current_thread_info = RELOCATED(&init_thread_union); | ||
343 | |||
344 | /* Return the new kernel's entry point */ | ||
345 | kernel_entry = RELOCATED(start_kernel); | ||
346 | } | ||
347 | out: | ||
348 | return kernel_entry; | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * Show relocation information on panic. | ||
353 | */ | ||
354 | void show_kernel_relocation(const char *level) | ||
355 | { | ||
356 | unsigned long offset; | ||
357 | |||
358 | offset = __pa_symbol(_text) - __pa_symbol(VMLINUX_LOAD_ADDRESS); | ||
359 | |||
360 | if (IS_ENABLED(CONFIG_RELOCATABLE) && offset > 0) { | ||
361 | printk(level); | ||
362 | pr_cont("Kernel relocated by 0x%pK\n", (void *)offset); | ||
363 | pr_cont(" .text @ 0x%pK\n", _text); | ||
364 | pr_cont(" .data @ 0x%pK\n", _sdata); | ||
365 | pr_cont(" .bss @ 0x%pK\n", __bss_start); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | static int kernel_location_notifier_fn(struct notifier_block *self, | ||
370 | unsigned long v, void *p) | ||
371 | { | ||
372 | show_kernel_relocation(KERN_EMERG); | ||
373 | return NOTIFY_DONE; | ||
374 | } | ||
375 | |||
376 | static struct notifier_block kernel_location_notifier = { | ||
377 | .notifier_call = kernel_location_notifier_fn | ||
378 | }; | ||
379 | |||
380 | static int __init register_kernel_offset_dumper(void) | ||
381 | { | ||
382 | atomic_notifier_chain_register(&panic_notifier_list, | ||
383 | &kernel_location_notifier); | ||
384 | return 0; | ||
385 | } | ||
386 | __initcall(register_kernel_offset_dumper); | ||
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index d01fe53a6638..c8e43e0c4066 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -35,7 +35,6 @@ NESTED(handle_sys, PT_SIZE, sp) | |||
35 | 35 | ||
36 | lw t1, PT_EPC(sp) # skip syscall on return | 36 | lw t1, PT_EPC(sp) # skip syscall on return |
37 | 37 | ||
38 | subu v0, v0, __NR_O32_Linux # check syscall number | ||
39 | addiu t1, 4 # skip to next instruction | 38 | addiu t1, 4 # skip to next instruction |
40 | sw t1, PT_EPC(sp) | 39 | sw t1, PT_EPC(sp) |
41 | 40 | ||
@@ -89,6 +88,7 @@ loads_done: | |||
89 | and t0, t1 | 88 | and t0, t1 |
90 | bnez t0, syscall_trace_entry # -> yes | 89 | bnez t0, syscall_trace_entry # -> yes |
91 | syscall_common: | 90 | syscall_common: |
91 | subu v0, v0, __NR_O32_Linux # check syscall number | ||
92 | sltiu t0, v0, __NR_O32_Linux_syscalls + 1 | 92 | sltiu t0, v0, __NR_O32_Linux_syscalls + 1 |
93 | beqz t0, illegal_syscall | 93 | beqz t0, illegal_syscall |
94 | 94 | ||
@@ -118,24 +118,23 @@ o32_syscall_exit: | |||
118 | 118 | ||
119 | syscall_trace_entry: | 119 | syscall_trace_entry: |
120 | SAVE_STATIC | 120 | SAVE_STATIC |
121 | move s0, v0 | ||
122 | move a0, sp | 121 | move a0, sp |
123 | 122 | ||
124 | /* | 123 | /* |
125 | * syscall number is in v0 unless we called syscall(__NR_###) | 124 | * syscall number is in v0 unless we called syscall(__NR_###) |
126 | * where the real syscall number is in a0 | 125 | * where the real syscall number is in a0 |
127 | */ | 126 | */ |
128 | addiu a1, v0, __NR_O32_Linux | 127 | move a1, v0 |
129 | bnez v0, 1f /* __NR_syscall at offset 0 */ | 128 | subu t2, v0, __NR_O32_Linux |
129 | bnez t2, 1f /* __NR_syscall at offset 0 */ | ||
130 | lw a1, PT_R4(sp) | 130 | lw a1, PT_R4(sp) |
131 | 131 | ||
132 | 1: jal syscall_trace_enter | 132 | 1: jal syscall_trace_enter |
133 | 133 | ||
134 | bltz v0, 1f # seccomp failed? Skip syscall | 134 | bltz v0, 1f # seccomp failed? Skip syscall |
135 | 135 | ||
136 | move v0, s0 # restore syscall | ||
137 | |||
138 | RESTORE_STATIC | 136 | RESTORE_STATIC |
137 | lw v0, PT_R2(sp) # Restore syscall (maybe modified) | ||
139 | lw a0, PT_R4(sp) # Restore argument registers | 138 | lw a0, PT_R4(sp) # Restore argument registers |
140 | lw a1, PT_R5(sp) | 139 | lw a1, PT_R5(sp) |
141 | lw a2, PT_R6(sp) | 140 | lw a2, PT_R6(sp) |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 6b73ecc02597..e6ede125059f 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -82,15 +82,14 @@ n64_syscall_exit: | |||
82 | 82 | ||
83 | syscall_trace_entry: | 83 | syscall_trace_entry: |
84 | SAVE_STATIC | 84 | SAVE_STATIC |
85 | move s0, v0 | ||
86 | move a0, sp | 85 | move a0, sp |
87 | move a1, v0 | 86 | move a1, v0 |
88 | jal syscall_trace_enter | 87 | jal syscall_trace_enter |
89 | 88 | ||
90 | bltz v0, 1f # seccomp failed? Skip syscall | 89 | bltz v0, 1f # seccomp failed? Skip syscall |
91 | 90 | ||
92 | move v0, s0 | ||
93 | RESTORE_STATIC | 91 | RESTORE_STATIC |
92 | ld v0, PT_R2(sp) # Restore syscall (maybe modified) | ||
94 | ld a0, PT_R4(sp) # Restore argument registers | 93 | ld a0, PT_R4(sp) # Restore argument registers |
95 | ld a1, PT_R5(sp) | 94 | ld a1, PT_R5(sp) |
96 | ld a2, PT_R6(sp) | 95 | ld a2, PT_R6(sp) |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 71f99d5f7a06..9c0b387d6427 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -42,9 +42,6 @@ NESTED(handle_sysn32, PT_SIZE, sp) | |||
42 | #endif | 42 | #endif |
43 | beqz t0, not_n32_scall | 43 | beqz t0, not_n32_scall |
44 | 44 | ||
45 | dsll t0, v0, 3 # offset into table | ||
46 | ld t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0) | ||
47 | |||
48 | sd a3, PT_R26(sp) # save a3 for syscall restarting | 45 | sd a3, PT_R26(sp) # save a3 for syscall restarting |
49 | 46 | ||
50 | li t1, _TIF_WORK_SYSCALL_ENTRY | 47 | li t1, _TIF_WORK_SYSCALL_ENTRY |
@@ -53,6 +50,9 @@ NESTED(handle_sysn32, PT_SIZE, sp) | |||
53 | bnez t0, n32_syscall_trace_entry | 50 | bnez t0, n32_syscall_trace_entry |
54 | 51 | ||
55 | syscall_common: | 52 | syscall_common: |
53 | dsll t0, v0, 3 # offset into table | ||
54 | ld t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0) | ||
55 | |||
56 | jalr t2 # Do The Real Thing (TM) | 56 | jalr t2 # Do The Real Thing (TM) |
57 | 57 | ||
58 | li t0, -EMAXERRNO - 1 # error? | 58 | li t0, -EMAXERRNO - 1 # error? |
@@ -71,21 +71,25 @@ syscall_common: | |||
71 | 71 | ||
72 | n32_syscall_trace_entry: | 72 | n32_syscall_trace_entry: |
73 | SAVE_STATIC | 73 | SAVE_STATIC |
74 | move s0, t2 | ||
75 | move a0, sp | 74 | move a0, sp |
76 | move a1, v0 | 75 | move a1, v0 |
77 | jal syscall_trace_enter | 76 | jal syscall_trace_enter |
78 | 77 | ||
79 | bltz v0, 1f # seccomp failed? Skip syscall | 78 | bltz v0, 1f # seccomp failed? Skip syscall |
80 | 79 | ||
81 | move t2, s0 | ||
82 | RESTORE_STATIC | 80 | RESTORE_STATIC |
81 | ld v0, PT_R2(sp) # Restore syscall (maybe modified) | ||
83 | ld a0, PT_R4(sp) # Restore argument registers | 82 | ld a0, PT_R4(sp) # Restore argument registers |
84 | ld a1, PT_R5(sp) | 83 | ld a1, PT_R5(sp) |
85 | ld a2, PT_R6(sp) | 84 | ld a2, PT_R6(sp) |
86 | ld a3, PT_R7(sp) | 85 | ld a3, PT_R7(sp) |
87 | ld a4, PT_R8(sp) | 86 | ld a4, PT_R8(sp) |
88 | ld a5, PT_R9(sp) | 87 | ld a5, PT_R9(sp) |
88 | |||
89 | dsubu t2, v0, __NR_N32_Linux # check (new) syscall number | ||
90 | sltiu t0, t2, __NR_N32_Linux_syscalls + 1 | ||
91 | beqz t0, not_n32_scall | ||
92 | |||
89 | j syscall_common | 93 | j syscall_common |
90 | 94 | ||
91 | 1: j syscall_exit | 95 | 1: j syscall_exit |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 91b43eea2d5a..f4f28b1580de 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -52,9 +52,6 @@ NESTED(handle_sys, PT_SIZE, sp) | |||
52 | sll a2, a2, 0 | 52 | sll a2, a2, 0 |
53 | sll a3, a3, 0 | 53 | sll a3, a3, 0 |
54 | 54 | ||
55 | dsll t0, v0, 3 # offset into table | ||
56 | ld t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0) | ||
57 | |||
58 | sd a3, PT_R26(sp) # save a3 for syscall restarting | 55 | sd a3, PT_R26(sp) # save a3 for syscall restarting |
59 | 56 | ||
60 | /* | 57 | /* |
@@ -88,6 +85,9 @@ loads_done: | |||
88 | bnez t0, trace_a_syscall | 85 | bnez t0, trace_a_syscall |
89 | 86 | ||
90 | syscall_common: | 87 | syscall_common: |
88 | dsll t0, v0, 3 # offset into table | ||
89 | ld t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0) | ||
90 | |||
91 | jalr t2 # Do The Real Thing (TM) | 91 | jalr t2 # Do The Real Thing (TM) |
92 | 92 | ||
93 | li t0, -EMAXERRNO - 1 # error? | 93 | li t0, -EMAXERRNO - 1 # error? |
@@ -112,7 +112,6 @@ trace_a_syscall: | |||
112 | sd a6, PT_R10(sp) | 112 | sd a6, PT_R10(sp) |
113 | sd a7, PT_R11(sp) # For indirect syscalls | 113 | sd a7, PT_R11(sp) # For indirect syscalls |
114 | 114 | ||
115 | move s0, t2 # Save syscall pointer | ||
116 | move a0, sp | 115 | move a0, sp |
117 | /* | 116 | /* |
118 | * absolute syscall number is in v0 unless we called syscall(__NR_###) | 117 | * absolute syscall number is in v0 unless we called syscall(__NR_###) |
@@ -133,8 +132,8 @@ trace_a_syscall: | |||
133 | 132 | ||
134 | bltz v0, 1f # seccomp failed? Skip syscall | 133 | bltz v0, 1f # seccomp failed? Skip syscall |
135 | 134 | ||
136 | move t2, s0 | ||
137 | RESTORE_STATIC | 135 | RESTORE_STATIC |
136 | ld v0, PT_R2(sp) # Restore syscall (maybe modified) | ||
138 | ld a0, PT_R4(sp) # Restore argument registers | 137 | ld a0, PT_R4(sp) # Restore argument registers |
139 | ld a1, PT_R5(sp) | 138 | ld a1, PT_R5(sp) |
140 | ld a2, PT_R6(sp) | 139 | ld a2, PT_R6(sp) |
@@ -143,6 +142,11 @@ trace_a_syscall: | |||
143 | ld a5, PT_R9(sp) | 142 | ld a5, PT_R9(sp) |
144 | ld a6, PT_R10(sp) | 143 | ld a6, PT_R10(sp) |
145 | ld a7, PT_R11(sp) # For indirect syscalls | 144 | ld a7, PT_R11(sp) # For indirect syscalls |
145 | |||
146 | dsubu t0, v0, __NR_O32_Linux # check (new) syscall number | ||
147 | sltiu t0, t0, __NR_O32_Linux_syscalls + 1 | ||
148 | beqz t0, not_o32_scall | ||
149 | |||
146 | j syscall_common | 150 | j syscall_common |
147 | 151 | ||
148 | 1: j syscall_exit | 152 | 1: j syscall_exit |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 4f607341a793..ef408a03e818 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/sizes.h> | 26 | #include <linux/sizes.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
28 | #include <linux/dma-contiguous.h> | 28 | #include <linux/dma-contiguous.h> |
29 | #include <linux/decompress/generic.h> | ||
29 | 30 | ||
30 | #include <asm/addrspace.h> | 31 | #include <asm/addrspace.h> |
31 | #include <asm/bootinfo.h> | 32 | #include <asm/bootinfo.h> |
@@ -52,13 +53,6 @@ struct screen_info screen_info; | |||
52 | #endif | 53 | #endif |
53 | 54 | ||
54 | /* | 55 | /* |
55 | * Despite it's name this variable is even if we don't have PCI | ||
56 | */ | ||
57 | unsigned int PCI_DMA_BUS_IS_PHYS; | ||
58 | |||
59 | EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS); | ||
60 | |||
61 | /* | ||
62 | * Setup information | 56 | * Setup information |
63 | * | 57 | * |
64 | * These are initialized so they are in the .data section | 58 | * These are initialized so they are in the .data section |
@@ -250,6 +244,35 @@ disable: | |||
250 | return 0; | 244 | return 0; |
251 | } | 245 | } |
252 | 246 | ||
247 | /* In some conditions (e.g. big endian bootloader with a little endian | ||
248 | kernel), the initrd might appear byte swapped. Try to detect this and | ||
249 | byte swap it if needed. */ | ||
250 | static void __init maybe_bswap_initrd(void) | ||
251 | { | ||
252 | #if defined(CONFIG_CPU_CAVIUM_OCTEON) | ||
253 | u64 buf; | ||
254 | |||
255 | /* Check for CPIO signature */ | ||
256 | if (!memcmp((void *)initrd_start, "070701", 6)) | ||
257 | return; | ||
258 | |||
259 | /* Check for compressed initrd */ | ||
260 | if (decompress_method((unsigned char *)initrd_start, 8, NULL)) | ||
261 | return; | ||
262 | |||
263 | /* Try again with a byte swapped header */ | ||
264 | buf = swab64p((u64 *)initrd_start); | ||
265 | if (!memcmp(&buf, "070701", 6) || | ||
266 | decompress_method((unsigned char *)(&buf), 8, NULL)) { | ||
267 | unsigned long i; | ||
268 | |||
269 | pr_info("Byteswapped initrd detected\n"); | ||
270 | for (i = initrd_start; i < ALIGN(initrd_end, 8); i += 8) | ||
271 | swab64s((u64 *)i); | ||
272 | } | ||
273 | #endif | ||
274 | } | ||
275 | |||
253 | static void __init finalize_initrd(void) | 276 | static void __init finalize_initrd(void) |
254 | { | 277 | { |
255 | unsigned long size = initrd_end - initrd_start; | 278 | unsigned long size = initrd_end - initrd_start; |
@@ -263,6 +286,8 @@ static void __init finalize_initrd(void) | |||
263 | goto disable; | 286 | goto disable; |
264 | } | 287 | } |
265 | 288 | ||
289 | maybe_bswap_initrd(); | ||
290 | |||
266 | reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT); | 291 | reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT); |
267 | initrd_below_start_ok = 1; | 292 | initrd_below_start_ok = 1; |
268 | 293 | ||
@@ -469,6 +494,29 @@ static void __init bootmem_init(void) | |||
469 | */ | 494 | */ |
470 | reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT); | 495 | reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT); |
471 | 496 | ||
497 | #ifdef CONFIG_RELOCATABLE | ||
498 | /* | ||
499 | * The kernel reserves all memory below its _end symbol as bootmem, | ||
500 | * but the kernel may now be at a much higher address. The memory | ||
501 | * between the original and new locations may be returned to the system. | ||
502 | */ | ||
503 | if (__pa_symbol(_text) > __pa_symbol(VMLINUX_LOAD_ADDRESS)) { | ||
504 | unsigned long offset; | ||
505 | extern void show_kernel_relocation(const char *level); | ||
506 | |||
507 | offset = __pa_symbol(_text) - __pa_symbol(VMLINUX_LOAD_ADDRESS); | ||
508 | free_bootmem(__pa_symbol(VMLINUX_LOAD_ADDRESS), offset); | ||
509 | |||
510 | #if defined(CONFIG_DEBUG_KERNEL) && defined(CONFIG_DEBUG_INFO) | ||
511 | /* | ||
512 | * This information is necessary when debugging the kernel | ||
513 | * But is a security vulnerability otherwise! | ||
514 | */ | ||
515 | show_kernel_relocation(KERN_INFO); | ||
516 | #endif | ||
517 | } | ||
518 | #endif | ||
519 | |||
472 | /* | 520 | /* |
473 | * Reserve initrd memory if needed. | 521 | * Reserve initrd memory if needed. |
474 | */ | 522 | */ |
@@ -624,6 +672,8 @@ static void __init request_crashkernel(struct resource *res) | |||
624 | #define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) | 672 | #define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) |
625 | #define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) | 673 | #define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) |
626 | #define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) | 674 | #define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) |
675 | #define BUILTIN_EXTEND_WITH_PROM \ | ||
676 | IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND) | ||
627 | 677 | ||
628 | static void __init arch_mem_init(char **cmdline_p) | 678 | static void __init arch_mem_init(char **cmdline_p) |
629 | { | 679 | { |
@@ -657,15 +707,23 @@ static void __init arch_mem_init(char **cmdline_p) | |||
657 | strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); | 707 | strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); |
658 | 708 | ||
659 | if (EXTEND_WITH_PROM && arcs_cmdline[0]) { | 709 | if (EXTEND_WITH_PROM && arcs_cmdline[0]) { |
660 | strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); | 710 | if (boot_command_line[0]) |
711 | strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); | ||
661 | strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); | 712 | strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); |
662 | } | 713 | } |
663 | 714 | ||
664 | #if defined(CONFIG_CMDLINE_BOOL) | 715 | #if defined(CONFIG_CMDLINE_BOOL) |
665 | if (builtin_cmdline[0]) { | 716 | if (builtin_cmdline[0]) { |
666 | strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); | 717 | if (boot_command_line[0]) |
718 | strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); | ||
667 | strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); | 719 | strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); |
668 | } | 720 | } |
721 | |||
722 | if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) { | ||
723 | if (boot_command_line[0]) | ||
724 | strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); | ||
725 | strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); | ||
726 | } | ||
669 | #endif | 727 | #endif |
670 | #endif | 728 | #endif |
671 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | 729 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
@@ -706,6 +764,9 @@ static void __init arch_mem_init(char **cmdline_p) | |||
706 | for_each_memblock(reserved, reg) | 764 | for_each_memblock(reserved, reg) |
707 | if (reg->size != 0) | 765 | if (reg->size != 0) |
708 | reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); | 766 | reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); |
767 | |||
768 | reserve_bootmem_region(__pa_symbol(&__nosave_begin), | ||
769 | __pa_symbol(&__nosave_end)); /* Reserve for hibernation */ | ||
709 | } | 770 | } |
710 | 771 | ||
711 | static void __init resource_init(void) | 772 | static void __init resource_init(void) |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index bf792e2839a6..ab042291fbfd 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -195,6 +195,9 @@ static int restore_msa_extcontext(void __user *buf, unsigned int size) | |||
195 | unsigned int csr; | 195 | unsigned int csr; |
196 | int i, err; | 196 | int i, err; |
197 | 197 | ||
198 | if (!config_enabled(CONFIG_CPU_HAS_MSA)) | ||
199 | return SIGSYS; | ||
200 | |||
198 | if (size != sizeof(*msa)) | 201 | if (size != sizeof(*msa)) |
199 | return -EINVAL; | 202 | return -EINVAL; |
200 | 203 | ||
@@ -398,8 +401,8 @@ int protected_restore_fp_context(void __user *sc) | |||
398 | } | 401 | } |
399 | 402 | ||
400 | fp_done: | 403 | fp_done: |
401 | if (used & USED_EXTCONTEXT) | 404 | if (!err && (used & USED_EXTCONTEXT)) |
402 | err |= restore_extcontext(sc_to_extcontext(sc)); | 405 | err = restore_extcontext(sc_to_extcontext(sc)); |
403 | 406 | ||
404 | return err ?: sig; | 407 | return err ?: sig; |
405 | } | 408 | } |
@@ -798,7 +801,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) | |||
798 | regs->regs[0] = 0; /* Don't deal with this again. */ | 801 | regs->regs[0] = 0; /* Don't deal with this again. */ |
799 | } | 802 | } |
800 | 803 | ||
801 | if (sig_uses_siginfo(&ksig->ka)) | 804 | if (sig_uses_siginfo(&ksig->ka, abi)) |
802 | ret = abi->setup_rt_frame(vdso + abi->vdso->off_rt_sigreturn, | 805 | ret = abi->setup_rt_frame(vdso + abi->vdso->off_rt_sigreturn, |
803 | ksig, regs, oldset); | 806 | ksig, regs, oldset); |
804 | else | 807 | else |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 4909639aa35b..78c8349d151c 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
@@ -227,6 +227,12 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) | |||
227 | err |= __put_user(from->si_uid, &to->si_uid); | 227 | err |= __put_user(from->si_uid, &to->si_uid); |
228 | err |= __put_user(from->si_int, &to->si_int); | 228 | err |= __put_user(from->si_int, &to->si_int); |
229 | break; | 229 | break; |
230 | case __SI_SYS >> 16: | ||
231 | err |= __copy_to_user(&to->si_call_addr, &from->si_call_addr, | ||
232 | sizeof(compat_uptr_t)); | ||
233 | err |= __put_user(from->si_syscall, &to->si_syscall); | ||
234 | err |= __put_user(from->si_arch, &to->si_arch); | ||
235 | break; | ||
230 | } | 236 | } |
231 | } | 237 | } |
232 | return err; | 238 | return err; |
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 78cf8c2f1de0..e02addc0307f 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c | |||
@@ -243,6 +243,7 @@ static void bmips_init_secondary(void) | |||
243 | break; | 243 | break; |
244 | case CPU_BMIPS5000: | 244 | case CPU_BMIPS5000: |
245 | write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); | 245 | write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); |
246 | current_cpu_data.core = (read_c0_brcm_config() >> 25) & 3; | ||
246 | break; | 247 | break; |
247 | } | 248 | } |
248 | } | 249 | } |
@@ -565,3 +566,90 @@ asmlinkage void __weak plat_wired_tlb_setup(void) | |||
565 | * once the wired entries are present. | 566 | * once the wired entries are present. |
566 | */ | 567 | */ |
567 | } | 568 | } |
569 | |||
570 | void __init bmips_cpu_setup(void) | ||
571 | { | ||
572 | void __iomem __maybe_unused *cbr = BMIPS_GET_CBR(); | ||
573 | u32 __maybe_unused cfg; | ||
574 | |||
575 | switch (current_cpu_type()) { | ||
576 | case CPU_BMIPS3300: | ||
577 | /* Set BIU to async mode */ | ||
578 | set_c0_brcm_bus_pll(BIT(22)); | ||
579 | __sync(); | ||
580 | |||
581 | /* put the BIU back in sync mode */ | ||
582 | clear_c0_brcm_bus_pll(BIT(22)); | ||
583 | |||
584 | /* clear BHTD to enable branch history table */ | ||
585 | clear_c0_brcm_reset(BIT(16)); | ||
586 | |||
587 | /* Flush and enable RAC */ | ||
588 | cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); | ||
589 | __raw_writel(cfg | 0x100, BMIPS_RAC_CONFIG); | ||
590 | __raw_readl(cbr + BMIPS_RAC_CONFIG); | ||
591 | |||
592 | cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); | ||
593 | __raw_writel(cfg | 0xf, BMIPS_RAC_CONFIG); | ||
594 | __raw_readl(cbr + BMIPS_RAC_CONFIG); | ||
595 | |||
596 | cfg = __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE); | ||
597 | __raw_writel(cfg | 0x0fff0000, cbr + BMIPS_RAC_ADDRESS_RANGE); | ||
598 | __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE); | ||
599 | break; | ||
600 | |||
601 | case CPU_BMIPS4380: | ||
602 | /* CBG workaround for early BMIPS4380 CPUs */ | ||
603 | switch (read_c0_prid()) { | ||
604 | case 0x2a040: | ||
605 | case 0x2a042: | ||
606 | case 0x2a044: | ||
607 | case 0x2a060: | ||
608 | cfg = __raw_readl(cbr + BMIPS_L2_CONFIG); | ||
609 | __raw_writel(cfg & ~0x07000000, cbr + BMIPS_L2_CONFIG); | ||
610 | __raw_readl(cbr + BMIPS_L2_CONFIG); | ||
611 | } | ||
612 | |||
613 | /* clear BHTD to enable branch history table */ | ||
614 | clear_c0_brcm_config_0(BIT(21)); | ||
615 | |||
616 | /* XI/ROTR enable */ | ||
617 | set_c0_brcm_config_0(BIT(23)); | ||
618 | set_c0_brcm_cmt_ctrl(BIT(15)); | ||
619 | break; | ||
620 | |||
621 | case CPU_BMIPS5000: | ||
622 | /* enable RDHWR, BRDHWR */ | ||
623 | set_c0_brcm_config(BIT(17) | BIT(21)); | ||
624 | |||
625 | /* Disable JTB */ | ||
626 | __asm__ __volatile__( | ||
627 | " .set noreorder\n" | ||
628 | " li $8, 0x5a455048\n" | ||
629 | " .word 0x4088b00f\n" /* mtc0 t0, $22, 15 */ | ||
630 | " .word 0x4008b008\n" /* mfc0 t0, $22, 8 */ | ||
631 | " li $9, 0x00008000\n" | ||
632 | " or $8, $8, $9\n" | ||
633 | " .word 0x4088b008\n" /* mtc0 t0, $22, 8 */ | ||
634 | " sync\n" | ||
635 | " li $8, 0x0\n" | ||
636 | " .word 0x4088b00f\n" /* mtc0 t0, $22, 15 */ | ||
637 | " .set reorder\n" | ||
638 | : : : "$8", "$9"); | ||
639 | |||
640 | /* XI enable */ | ||
641 | set_c0_brcm_config(BIT(27)); | ||
642 | |||
643 | /* enable MIPS32R2 ROR instruction for XI TLB handlers */ | ||
644 | __asm__ __volatile__( | ||
645 | " li $8, 0x5a455048\n" | ||
646 | " .word 0x4088b00f\n" /* mtc0 $8, $22, 15 */ | ||
647 | " nop; nop; nop\n" | ||
648 | " .word 0x4008b008\n" /* mfc0 $8, $22, 8 */ | ||
649 | " lui $9, 0x0100\n" | ||
650 | " or $8, $9\n" | ||
651 | " .word 0x4088b008\n" /* mtc0 $8, $22, 8 */ | ||
652 | : : : "$8", "$9"); | ||
653 | break; | ||
654 | } | ||
655 | } | ||
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 253e1409338c..1061bd2e7e9c 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c | |||
@@ -27,15 +27,27 @@ | |||
27 | #include <asm/time.h> | 27 | #include <asm/time.h> |
28 | #include <asm/uasm.h> | 28 | #include <asm/uasm.h> |
29 | 29 | ||
30 | static bool threads_disabled; | ||
30 | static DECLARE_BITMAP(core_power, NR_CPUS); | 31 | static DECLARE_BITMAP(core_power, NR_CPUS); |
31 | 32 | ||
32 | struct core_boot_config *mips_cps_core_bootcfg; | 33 | struct core_boot_config *mips_cps_core_bootcfg; |
33 | 34 | ||
35 | static int __init setup_nothreads(char *s) | ||
36 | { | ||
37 | threads_disabled = true; | ||
38 | return 0; | ||
39 | } | ||
40 | early_param("nothreads", setup_nothreads); | ||
41 | |||
34 | static unsigned core_vpe_count(unsigned core) | 42 | static unsigned core_vpe_count(unsigned core) |
35 | { | 43 | { |
36 | unsigned cfg; | 44 | unsigned cfg; |
37 | 45 | ||
38 | if (!config_enabled(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt) | 46 | if (threads_disabled) |
47 | return 1; | ||
48 | |||
49 | if ((!config_enabled(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt) | ||
50 | && (!config_enabled(CONFIG_CPU_MIPSR6) || !cpu_has_vp)) | ||
39 | return 1; | 51 | return 1; |
40 | 52 | ||
41 | mips_cm_lock_other(core, 0); | 53 | mips_cm_lock_other(core, 0); |
@@ -47,11 +59,12 @@ static unsigned core_vpe_count(unsigned core) | |||
47 | static void __init cps_smp_setup(void) | 59 | static void __init cps_smp_setup(void) |
48 | { | 60 | { |
49 | unsigned int ncores, nvpes, core_vpes; | 61 | unsigned int ncores, nvpes, core_vpes; |
62 | unsigned long core_entry; | ||
50 | int c, v; | 63 | int c, v; |
51 | 64 | ||
52 | /* Detect & record VPE topology */ | 65 | /* Detect & record VPE topology */ |
53 | ncores = mips_cm_numcores(); | 66 | ncores = mips_cm_numcores(); |
54 | pr_info("VPE topology "); | 67 | pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE"); |
55 | for (c = nvpes = 0; c < ncores; c++) { | 68 | for (c = nvpes = 0; c < ncores; c++) { |
56 | core_vpes = core_vpe_count(c); | 69 | core_vpes = core_vpe_count(c); |
57 | pr_cont("%c%u", c ? ',' : '{', core_vpes); | 70 | pr_cont("%c%u", c ? ',' : '{', core_vpes); |
@@ -62,7 +75,7 @@ static void __init cps_smp_setup(void) | |||
62 | 75 | ||
63 | for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) { | 76 | for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) { |
64 | cpu_data[nvpes + v].core = c; | 77 | cpu_data[nvpes + v].core = c; |
65 | #ifdef CONFIG_MIPS_MT_SMP | 78 | #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) |
66 | cpu_data[nvpes + v].vpe_id = v; | 79 | cpu_data[nvpes + v].vpe_id = v; |
67 | #endif | 80 | #endif |
68 | } | 81 | } |
@@ -91,6 +104,11 @@ static void __init cps_smp_setup(void) | |||
91 | /* Make core 0 coherent with everything */ | 104 | /* Make core 0 coherent with everything */ |
92 | write_gcr_cl_coherence(0xff); | 105 | write_gcr_cl_coherence(0xff); |
93 | 106 | ||
107 | if (mips_cm_revision() >= CM_REV_CM3) { | ||
108 | core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry); | ||
109 | write_gcr_bev_base(core_entry); | ||
110 | } | ||
111 | |||
94 | #ifdef CONFIG_MIPS_MT_FPAFF | 112 | #ifdef CONFIG_MIPS_MT_FPAFF |
95 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | 113 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ |
96 | if (cpu_has_fpu) | 114 | if (cpu_has_fpu) |
@@ -213,6 +231,18 @@ static void boot_core(unsigned core) | |||
213 | if (mips_cpc_present()) { | 231 | if (mips_cpc_present()) { |
214 | /* Reset the core */ | 232 | /* Reset the core */ |
215 | mips_cpc_lock_other(core); | 233 | mips_cpc_lock_other(core); |
234 | |||
235 | if (mips_cm_revision() >= CM_REV_CM3) { | ||
236 | /* Run VP0 following the reset */ | ||
237 | write_cpc_co_vp_run(0x1); | ||
238 | |||
239 | /* | ||
240 | * Ensure that the VP_RUN register is written before the | ||
241 | * core leaves reset. | ||
242 | */ | ||
243 | wmb(); | ||
244 | } | ||
245 | |||
216 | write_cpc_co_cmd(CPC_Cx_CMD_RESET); | 246 | write_cpc_co_cmd(CPC_Cx_CMD_RESET); |
217 | 247 | ||
218 | timeout = 100; | 248 | timeout = 100; |
@@ -250,7 +280,10 @@ static void boot_core(unsigned core) | |||
250 | 280 | ||
251 | static void remote_vpe_boot(void *dummy) | 281 | static void remote_vpe_boot(void *dummy) |
252 | { | 282 | { |
253 | mips_cps_boot_vpes(); | 283 | unsigned core = current_cpu_data.core; |
284 | struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; | ||
285 | |||
286 | mips_cps_boot_vpes(core_cfg, cpu_vpe_id(¤t_cpu_data)); | ||
254 | } | 287 | } |
255 | 288 | ||
256 | static void cps_boot_secondary(int cpu, struct task_struct *idle) | 289 | static void cps_boot_secondary(int cpu, struct task_struct *idle) |
@@ -259,6 +292,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) | |||
259 | unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); | 292 | unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); |
260 | struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; | 293 | struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; |
261 | struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id]; | 294 | struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id]; |
295 | unsigned long core_entry; | ||
262 | unsigned int remote; | 296 | unsigned int remote; |
263 | int err; | 297 | int err; |
264 | 298 | ||
@@ -276,6 +310,13 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) | |||
276 | goto out; | 310 | goto out; |
277 | } | 311 | } |
278 | 312 | ||
313 | if (cpu_has_vp) { | ||
314 | mips_cm_lock_other(core, vpe_id); | ||
315 | core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry); | ||
316 | write_gcr_co_reset_base(core_entry); | ||
317 | mips_cm_unlock_other(); | ||
318 | } | ||
319 | |||
279 | if (core != current_cpu_data.core) { | 320 | if (core != current_cpu_data.core) { |
280 | /* Boot a VPE on another powered up core */ | 321 | /* Boot a VPE on another powered up core */ |
281 | for (remote = 0; remote < NR_CPUS; remote++) { | 322 | for (remote = 0; remote < NR_CPUS; remote++) { |
@@ -293,10 +334,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) | |||
293 | goto out; | 334 | goto out; |
294 | } | 335 | } |
295 | 336 | ||
296 | BUG_ON(!cpu_has_mipsmt); | 337 | BUG_ON(!cpu_has_mipsmt && !cpu_has_vp); |
297 | 338 | ||
298 | /* Boot a VPE on this core */ | 339 | /* Boot a VPE on this core */ |
299 | mips_cps_boot_vpes(); | 340 | mips_cps_boot_vpes(core_cfg, vpe_id); |
300 | out: | 341 | out: |
301 | preempt_enable(); | 342 | preempt_enable(); |
302 | } | 343 | } |
@@ -307,6 +348,17 @@ static void cps_init_secondary(void) | |||
307 | if (cpu_has_mipsmt) | 348 | if (cpu_has_mipsmt) |
308 | dmt(); | 349 | dmt(); |
309 | 350 | ||
351 | if (mips_cm_revision() >= CM_REV_CM3) { | ||
352 | unsigned ident = gic_read_local_vp_id(); | ||
353 | |||
354 | /* | ||
355 | * Ensure that our calculation of the VP ID matches up with | ||
356 | * what the GIC reports, otherwise we'll have configured | ||
357 | * interrupts incorrectly. | ||
358 | */ | ||
359 | BUG_ON(ident != mips_cm_vp_id(smp_processor_id())); | ||
360 | } | ||
361 | |||
310 | change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | | 362 | change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | |
311 | STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7); | 363 | STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7); |
312 | } | 364 | } |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 27cb638f0824..f9d01e953acb 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -243,18 +243,6 @@ static int __init mips_smp_ipi_init(void) | |||
243 | struct irq_domain *ipidomain; | 243 | struct irq_domain *ipidomain; |
244 | struct device_node *node; | 244 | struct device_node *node; |
245 | 245 | ||
246 | /* | ||
247 | * In some cases like qemu-malta, it is desired to try SMP with | ||
248 | * a single core. Qemu-malta has no GIC, so an attempt to set any IPIs | ||
249 | * would cause a BUG_ON() to be triggered since there's no ipidomain. | ||
250 | * | ||
251 | * Since for a single core system IPIs aren't required really, skip the | ||
252 | * initialisation which should generally keep any such configurations | ||
253 | * happy and only fail hard when trying to truely run SMP. | ||
254 | */ | ||
255 | if (cpumask_weight(cpu_possible_mask) == 1) | ||
256 | return 0; | ||
257 | |||
258 | node = of_irq_find_parent(of_root); | 246 | node = of_irq_find_parent(of_root); |
259 | ipidomain = irq_find_matching_host(node, DOMAIN_BUS_IPI); | 247 | ipidomain = irq_find_matching_host(node, DOMAIN_BUS_IPI); |
260 | 248 | ||
@@ -266,7 +254,17 @@ static int __init mips_smp_ipi_init(void) | |||
266 | if (node && !ipidomain) | 254 | if (node && !ipidomain) |
267 | ipidomain = irq_find_matching_host(NULL, DOMAIN_BUS_IPI); | 255 | ipidomain = irq_find_matching_host(NULL, DOMAIN_BUS_IPI); |
268 | 256 | ||
269 | BUG_ON(!ipidomain); | 257 | /* |
258 | * There are systems which only use IPI domains some of the time, | ||
259 | * depending upon configuration we don't know until runtime. An | ||
260 | * example is Malta where we may compile in support for GIC & the | ||
261 | * MT ASE, but run on a system which has multiple VPEs in a single | ||
262 | * core and doesn't include a GIC. Until all IPI implementations | ||
263 | * have been converted to use IPI domains the best we can do here | ||
264 | * is to return & hope some other code sets up the IPIs. | ||
265 | */ | ||
266 | if (!ipidomain) | ||
267 | return 0; | ||
270 | 268 | ||
271 | call_virq = irq_reserve_ipi(ipidomain, cpu_possible_mask); | 269 | call_virq = irq_reserve_ipi(ipidomain, cpu_possible_mask); |
272 | BUG_ON(!call_virq); | 270 | BUG_ON(!call_virq); |
diff --git a/arch/mips/kernel/spram.c b/arch/mips/kernel/spram.c index 8489c88f9932..d6e6cf75114d 100644 --- a/arch/mips/kernel/spram.c +++ b/arch/mips/kernel/spram.c | |||
@@ -210,6 +210,7 @@ void spram_config(void) | |||
210 | case CPU_P5600: | 210 | case CPU_P5600: |
211 | case CPU_QEMU_GENERIC: | 211 | case CPU_QEMU_GENERIC: |
212 | case CPU_I6400: | 212 | case CPU_I6400: |
213 | case CPU_P6600: | ||
213 | config0 = read_c0_config(); | 214 | config0 = read_c0_config(); |
214 | /* FIXME: addresses are Malta specific */ | 215 | /* FIXME: addresses are Malta specific */ |
215 | if (config0 & (1<<24)) { | 216 | if (config0 & (1<<24)) { |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index ae0c89d23ad7..4a1712b5abdf 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -145,7 +145,7 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs) | |||
145 | if (!task) | 145 | if (!task) |
146 | task = current; | 146 | task = current; |
147 | 147 | ||
148 | if (raw_show_trace || !__kernel_text_address(pc)) { | 148 | if (raw_show_trace || user_mode(regs) || !__kernel_text_address(pc)) { |
149 | show_raw_backtrace(sp); | 149 | show_raw_backtrace(sp); |
150 | return; | 150 | return; |
151 | } | 151 | } |
@@ -399,11 +399,8 @@ void __noreturn die(const char *str, struct pt_regs *regs) | |||
399 | if (in_interrupt()) | 399 | if (in_interrupt()) |
400 | panic("Fatal exception in interrupt"); | 400 | panic("Fatal exception in interrupt"); |
401 | 401 | ||
402 | if (panic_on_oops) { | 402 | if (panic_on_oops) |
403 | printk(KERN_EMERG "Fatal exception: panic in 5 seconds"); | ||
404 | ssleep(5); | ||
405 | panic("Fatal exception"); | 403 | panic("Fatal exception"); |
406 | } | ||
407 | 404 | ||
408 | if (regs && kexec_should_crash(current)) | 405 | if (regs && kexec_should_crash(current)) |
409 | crash_kexec(regs); | 406 | crash_kexec(regs); |
@@ -1249,7 +1246,7 @@ static int enable_restore_fp_context(int msa) | |||
1249 | err = init_fpu(); | 1246 | err = init_fpu(); |
1250 | if (msa && !err) { | 1247 | if (msa && !err) { |
1251 | enable_msa(); | 1248 | enable_msa(); |
1252 | _init_msa_upper(); | 1249 | init_msa_upper(); |
1253 | set_thread_flag(TIF_USEDMSA); | 1250 | set_thread_flag(TIF_USEDMSA); |
1254 | set_thread_flag(TIF_MSA_CTX_LIVE); | 1251 | set_thread_flag(TIF_MSA_CTX_LIVE); |
1255 | } | 1252 | } |
@@ -1312,7 +1309,7 @@ static int enable_restore_fp_context(int msa) | |||
1312 | */ | 1309 | */ |
1313 | prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE); | 1310 | prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE); |
1314 | if (!prior_msa && was_fpu_owner) { | 1311 | if (!prior_msa && was_fpu_owner) { |
1315 | _init_msa_upper(); | 1312 | init_msa_upper(); |
1316 | 1313 | ||
1317 | goto out; | 1314 | goto out; |
1318 | } | 1315 | } |
@@ -1329,7 +1326,7 @@ static int enable_restore_fp_context(int msa) | |||
1329 | * of each vector register such that it cannot see data left | 1326 | * of each vector register such that it cannot see data left |
1330 | * behind by another task. | 1327 | * behind by another task. |
1331 | */ | 1328 | */ |
1332 | _init_msa_upper(); | 1329 | init_msa_upper(); |
1333 | } else { | 1330 | } else { |
1334 | /* We need to restore the vector context. */ | 1331 | /* We need to restore the vector context. */ |
1335 | restore_msa(current); | 1332 | restore_msa(current); |
@@ -1356,7 +1353,6 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
1356 | unsigned long fcr31; | 1353 | unsigned long fcr31; |
1357 | unsigned int cpid; | 1354 | unsigned int cpid; |
1358 | int status, err; | 1355 | int status, err; |
1359 | unsigned long __maybe_unused flags; | ||
1360 | int sig; | 1356 | int sig; |
1361 | 1357 | ||
1362 | prev_state = exception_enter(); | 1358 | prev_state = exception_enter(); |
@@ -1501,16 +1497,13 @@ asmlinkage void do_watch(struct pt_regs *regs) | |||
1501 | { | 1497 | { |
1502 | siginfo_t info = { .si_signo = SIGTRAP, .si_code = TRAP_HWBKPT }; | 1498 | siginfo_t info = { .si_signo = SIGTRAP, .si_code = TRAP_HWBKPT }; |
1503 | enum ctx_state prev_state; | 1499 | enum ctx_state prev_state; |
1504 | u32 cause; | ||
1505 | 1500 | ||
1506 | prev_state = exception_enter(); | 1501 | prev_state = exception_enter(); |
1507 | /* | 1502 | /* |
1508 | * Clear WP (bit 22) bit of cause register so we don't loop | 1503 | * Clear WP (bit 22) bit of cause register so we don't loop |
1509 | * forever. | 1504 | * forever. |
1510 | */ | 1505 | */ |
1511 | cause = read_c0_cause(); | 1506 | clear_c0_cause(CAUSEF_WP); |
1512 | cause &= ~(1 << 22); | ||
1513 | write_c0_cause(cause); | ||
1514 | 1507 | ||
1515 | /* | 1508 | /* |
1516 | * If the current thread has the watch registers loaded, save | 1509 | * If the current thread has the watch registers loaded, save |
@@ -1647,6 +1640,7 @@ static inline void parity_protection_init(void) | |||
1647 | case CPU_P5600: | 1640 | case CPU_P5600: |
1648 | case CPU_QEMU_GENERIC: | 1641 | case CPU_QEMU_GENERIC: |
1649 | case CPU_I6400: | 1642 | case CPU_I6400: |
1643 | case CPU_P6600: | ||
1650 | { | 1644 | { |
1651 | #define ERRCTL_PE 0x80000000 | 1645 | #define ERRCTL_PE 0x80000000 |
1652 | #define ERRCTL_L2P 0x00800000 | 1646 | #define ERRCTL_L2P 0x00800000 |
@@ -1777,7 +1771,8 @@ asmlinkage void do_ftlb(void) | |||
1777 | 1771 | ||
1778 | /* For the moment, report the problem and hang. */ | 1772 | /* For the moment, report the problem and hang. */ |
1779 | if ((cpu_has_mips_r2_r6) && | 1773 | if ((cpu_has_mips_r2_r6) && |
1780 | ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS)) { | 1774 | (((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS) || |
1775 | ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_LOONGSON))) { | ||
1781 | pr_err("FTLB error exception, cp0_ecc=0x%08x:\n", | 1776 | pr_err("FTLB error exception, cp0_ecc=0x%08x:\n", |
1782 | read_c0_ecc()); | 1777 | read_c0_ecc()); |
1783 | pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); | 1778 | pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); |
@@ -2119,6 +2114,13 @@ void per_cpu_trap_init(bool is_boot_cpu) | |||
2119 | * o read IntCtl.IPFDC to determine the fast debug channel interrupt | 2114 | * o read IntCtl.IPFDC to determine the fast debug channel interrupt |
2120 | */ | 2115 | */ |
2121 | if (cpu_has_mips_r2_r6) { | 2116 | if (cpu_has_mips_r2_r6) { |
2117 | /* | ||
2118 | * We shouldn't trust a secondary core has a sane EBASE register | ||
2119 | * so use the one calculated by the boot CPU. | ||
2120 | */ | ||
2121 | if (!is_boot_cpu) | ||
2122 | write_c0_ebase(ebase); | ||
2123 | |||
2122 | cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; | 2124 | cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; |
2123 | cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; | 2125 | cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; |
2124 | cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; | 2126 | cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; |
@@ -2134,7 +2136,7 @@ void per_cpu_trap_init(bool is_boot_cpu) | |||
2134 | } | 2136 | } |
2135 | 2137 | ||
2136 | if (!cpu_data[cpu].asid_cache) | 2138 | if (!cpu_data[cpu].asid_cache) |
2137 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; | 2139 | cpu_data[cpu].asid_cache = asid_first_version(cpu); |
2138 | 2140 | ||
2139 | atomic_inc(&init_mm.mm_count); | 2141 | atomic_inc(&init_mm.mm_count); |
2140 | current->active_mm = &init_mm; | 2142 | current->active_mm = &init_mm; |
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 5c62065cbf22..28b3af73a17b 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c | |||
@@ -1191,6 +1191,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
1191 | case ldc1_op: | 1191 | case ldc1_op: |
1192 | case swc1_op: | 1192 | case swc1_op: |
1193 | case sdc1_op: | 1193 | case sdc1_op: |
1194 | case cop1x_op: | ||
1194 | die_if_kernel("Unaligned FP access in kernel code", regs); | 1195 | die_if_kernel("Unaligned FP access in kernel code", regs); |
1195 | BUG_ON(!used_math()); | 1196 | BUG_ON(!used_math()); |
1196 | 1197 | ||
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 54d653ee17e1..a82c178d0bb9 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -136,6 +136,27 @@ SECTIONS | |||
136 | #ifdef CONFIG_SMP | 136 | #ifdef CONFIG_SMP |
137 | PERCPU_SECTION(1 << CONFIG_MIPS_L1_CACHE_SHIFT) | 137 | PERCPU_SECTION(1 << CONFIG_MIPS_L1_CACHE_SHIFT) |
138 | #endif | 138 | #endif |
139 | |||
140 | #ifdef CONFIG_RELOCATABLE | ||
141 | . = ALIGN(4); | ||
142 | |||
143 | .data.reloc : { | ||
144 | _relocation_start = .; | ||
145 | /* | ||
146 | * Space for relocation table | ||
147 | * This needs to be filled so that the | ||
148 | * relocs tool can overwrite the content. | ||
149 | * An invalid value is left at the start of the | ||
150 | * section to abort relocation if the table | ||
151 | * has not been filled in. | ||
152 | */ | ||
153 | LONG(0xFFFFFFFF); | ||
154 | FILL(0); | ||
155 | . += CONFIG_RELOCATION_TABLE_SIZE - 4; | ||
156 | _relocation_end = .; | ||
157 | } | ||
158 | #endif | ||
159 | |||
139 | #ifdef CONFIG_MIPS_RAW_APPENDED_DTB | 160 | #ifdef CONFIG_MIPS_RAW_APPENDED_DTB |
140 | __appended_dtb = .; | 161 | __appended_dtb = .; |
141 | /* leave space for appended DTB */ | 162 | /* leave space for appended DTB */ |
diff --git a/arch/mips/kernel/watch.c b/arch/mips/kernel/watch.c index 2a03abb5bd2c..19fcab7348b1 100644 --- a/arch/mips/kernel/watch.c +++ b/arch/mips/kernel/watch.c | |||
@@ -15,10 +15,9 @@ | |||
15 | * Install the watch registers for the current thread. A maximum of | 15 | * Install the watch registers for the current thread. A maximum of |
16 | * four registers are installed although the machine may have more. | 16 | * four registers are installed although the machine may have more. |
17 | */ | 17 | */ |
18 | void mips_install_watch_registers(void) | 18 | void mips_install_watch_registers(struct task_struct *t) |
19 | { | 19 | { |
20 | struct mips3264_watch_reg_state *watches = | 20 | struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264; |
21 | ¤t->thread.watch.mips3264; | ||
22 | switch (current_cpu_data.watch_reg_use_cnt) { | 21 | switch (current_cpu_data.watch_reg_use_cnt) { |
23 | default: | 22 | default: |
24 | BUG(); | 23 | BUG(); |
@@ -26,16 +25,20 @@ void mips_install_watch_registers(void) | |||
26 | write_c0_watchlo3(watches->watchlo[3]); | 25 | write_c0_watchlo3(watches->watchlo[3]); |
27 | /* Write 1 to the I, R, and W bits to clear them, and | 26 | /* Write 1 to the I, R, and W bits to clear them, and |
28 | 1 to G so all ASIDs are trapped. */ | 27 | 1 to G so all ASIDs are trapped. */ |
29 | write_c0_watchhi3(0x40000007 | watches->watchhi[3]); | 28 | write_c0_watchhi3(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | |
29 | watches->watchhi[3]); | ||
30 | case 3: | 30 | case 3: |
31 | write_c0_watchlo2(watches->watchlo[2]); | 31 | write_c0_watchlo2(watches->watchlo[2]); |
32 | write_c0_watchhi2(0x40000007 | watches->watchhi[2]); | 32 | write_c0_watchhi2(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | |
33 | watches->watchhi[2]); | ||
33 | case 2: | 34 | case 2: |
34 | write_c0_watchlo1(watches->watchlo[1]); | 35 | write_c0_watchlo1(watches->watchlo[1]); |
35 | write_c0_watchhi1(0x40000007 | watches->watchhi[1]); | 36 | write_c0_watchhi1(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | |
37 | watches->watchhi[1]); | ||
36 | case 1: | 38 | case 1: |
37 | write_c0_watchlo0(watches->watchlo[0]); | 39 | write_c0_watchlo0(watches->watchlo[0]); |
38 | write_c0_watchhi0(0x40000007 | watches->watchhi[0]); | 40 | write_c0_watchhi0(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | |
41 | watches->watchhi[0]); | ||
39 | } | 42 | } |
40 | } | 43 | } |
41 | 44 | ||
@@ -52,22 +55,26 @@ void mips_read_watch_registers(void) | |||
52 | default: | 55 | default: |
53 | BUG(); | 56 | BUG(); |
54 | case 4: | 57 | case 4: |
55 | watches->watchhi[3] = (read_c0_watchhi3() & 0x0fff); | 58 | watches->watchhi[3] = (read_c0_watchhi3() & |
59 | (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); | ||
56 | case 3: | 60 | case 3: |
57 | watches->watchhi[2] = (read_c0_watchhi2() & 0x0fff); | 61 | watches->watchhi[2] = (read_c0_watchhi2() & |
62 | (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); | ||
58 | case 2: | 63 | case 2: |
59 | watches->watchhi[1] = (read_c0_watchhi1() & 0x0fff); | 64 | watches->watchhi[1] = (read_c0_watchhi1() & |
65 | (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); | ||
60 | case 1: | 66 | case 1: |
61 | watches->watchhi[0] = (read_c0_watchhi0() & 0x0fff); | 67 | watches->watchhi[0] = (read_c0_watchhi0() & |
68 | (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); | ||
62 | } | 69 | } |
63 | if (current_cpu_data.watch_reg_use_cnt == 1 && | 70 | if (current_cpu_data.watch_reg_use_cnt == 1 && |
64 | (watches->watchhi[0] & 7) == 0) { | 71 | (watches->watchhi[0] & MIPS_WATCHHI_IRW) == 0) { |
65 | /* Pathological case of release 1 architecture that | 72 | /* Pathological case of release 1 architecture that |
66 | * doesn't set the condition bits. We assume that | 73 | * doesn't set the condition bits. We assume that |
67 | * since we got here, the watch condition was met and | 74 | * since we got here, the watch condition was met and |
68 | * signal that the conditions requested in watchlo | 75 | * signal that the conditions requested in watchlo |
69 | * were met. */ | 76 | * were met. */ |
70 | watches->watchhi[0] |= (watches->watchlo[0] & 7); | 77 | watches->watchhi[0] |= (watches->watchlo[0] & MIPS_WATCHHI_IRW); |
71 | } | 78 | } |
72 | } | 79 | } |
73 | 80 | ||
@@ -110,86 +117,86 @@ void mips_probe_watch_registers(struct cpuinfo_mips *c) | |||
110 | * Check which of the I,R and W bits are supported, then | 117 | * Check which of the I,R and W bits are supported, then |
111 | * disable the register. | 118 | * disable the register. |
112 | */ | 119 | */ |
113 | write_c0_watchlo0(7); | 120 | write_c0_watchlo0(MIPS_WATCHLO_IRW); |
114 | back_to_back_c0_hazard(); | 121 | back_to_back_c0_hazard(); |
115 | t = read_c0_watchlo0(); | 122 | t = read_c0_watchlo0(); |
116 | write_c0_watchlo0(0); | 123 | write_c0_watchlo0(0); |
117 | c->watch_reg_masks[0] = t & 7; | 124 | c->watch_reg_masks[0] = t & MIPS_WATCHLO_IRW; |
118 | 125 | ||
119 | /* Write the mask bits and read them back to determine which | 126 | /* Write the mask bits and read them back to determine which |
120 | * can be used. */ | 127 | * can be used. */ |
121 | c->watch_reg_count = 1; | 128 | c->watch_reg_count = 1; |
122 | c->watch_reg_use_cnt = 1; | 129 | c->watch_reg_use_cnt = 1; |
123 | t = read_c0_watchhi0(); | 130 | t = read_c0_watchhi0(); |
124 | write_c0_watchhi0(t | 0xff8); | 131 | write_c0_watchhi0(t | MIPS_WATCHHI_MASK); |
125 | back_to_back_c0_hazard(); | 132 | back_to_back_c0_hazard(); |
126 | t = read_c0_watchhi0(); | 133 | t = read_c0_watchhi0(); |
127 | c->watch_reg_masks[0] |= (t & 0xff8); | 134 | c->watch_reg_masks[0] |= (t & MIPS_WATCHHI_MASK); |
128 | if ((t & 0x80000000) == 0) | 135 | if ((t & MIPS_WATCHHI_M) == 0) |
129 | return; | 136 | return; |
130 | 137 | ||
131 | write_c0_watchlo1(7); | 138 | write_c0_watchlo1(MIPS_WATCHLO_IRW); |
132 | back_to_back_c0_hazard(); | 139 | back_to_back_c0_hazard(); |
133 | t = read_c0_watchlo1(); | 140 | t = read_c0_watchlo1(); |
134 | write_c0_watchlo1(0); | 141 | write_c0_watchlo1(0); |
135 | c->watch_reg_masks[1] = t & 7; | 142 | c->watch_reg_masks[1] = t & MIPS_WATCHLO_IRW; |
136 | 143 | ||
137 | c->watch_reg_count = 2; | 144 | c->watch_reg_count = 2; |
138 | c->watch_reg_use_cnt = 2; | 145 | c->watch_reg_use_cnt = 2; |
139 | t = read_c0_watchhi1(); | 146 | t = read_c0_watchhi1(); |
140 | write_c0_watchhi1(t | 0xff8); | 147 | write_c0_watchhi1(t | MIPS_WATCHHI_MASK); |
141 | back_to_back_c0_hazard(); | 148 | back_to_back_c0_hazard(); |
142 | t = read_c0_watchhi1(); | 149 | t = read_c0_watchhi1(); |
143 | c->watch_reg_masks[1] |= (t & 0xff8); | 150 | c->watch_reg_masks[1] |= (t & MIPS_WATCHHI_MASK); |
144 | if ((t & 0x80000000) == 0) | 151 | if ((t & MIPS_WATCHHI_M) == 0) |
145 | return; | 152 | return; |
146 | 153 | ||
147 | write_c0_watchlo2(7); | 154 | write_c0_watchlo2(MIPS_WATCHLO_IRW); |
148 | back_to_back_c0_hazard(); | 155 | back_to_back_c0_hazard(); |
149 | t = read_c0_watchlo2(); | 156 | t = read_c0_watchlo2(); |
150 | write_c0_watchlo2(0); | 157 | write_c0_watchlo2(0); |
151 | c->watch_reg_masks[2] = t & 7; | 158 | c->watch_reg_masks[2] = t & MIPS_WATCHLO_IRW; |
152 | 159 | ||
153 | c->watch_reg_count = 3; | 160 | c->watch_reg_count = 3; |
154 | c->watch_reg_use_cnt = 3; | 161 | c->watch_reg_use_cnt = 3; |
155 | t = read_c0_watchhi2(); | 162 | t = read_c0_watchhi2(); |
156 | write_c0_watchhi2(t | 0xff8); | 163 | write_c0_watchhi2(t | MIPS_WATCHHI_MASK); |
157 | back_to_back_c0_hazard(); | 164 | back_to_back_c0_hazard(); |
158 | t = read_c0_watchhi2(); | 165 | t = read_c0_watchhi2(); |
159 | c->watch_reg_masks[2] |= (t & 0xff8); | 166 | c->watch_reg_masks[2] |= (t & MIPS_WATCHHI_MASK); |
160 | if ((t & 0x80000000) == 0) | 167 | if ((t & MIPS_WATCHHI_M) == 0) |
161 | return; | 168 | return; |
162 | 169 | ||
163 | write_c0_watchlo3(7); | 170 | write_c0_watchlo3(MIPS_WATCHLO_IRW); |
164 | back_to_back_c0_hazard(); | 171 | back_to_back_c0_hazard(); |
165 | t = read_c0_watchlo3(); | 172 | t = read_c0_watchlo3(); |
166 | write_c0_watchlo3(0); | 173 | write_c0_watchlo3(0); |
167 | c->watch_reg_masks[3] = t & 7; | 174 | c->watch_reg_masks[3] = t & MIPS_WATCHLO_IRW; |
168 | 175 | ||
169 | c->watch_reg_count = 4; | 176 | c->watch_reg_count = 4; |
170 | c->watch_reg_use_cnt = 4; | 177 | c->watch_reg_use_cnt = 4; |
171 | t = read_c0_watchhi3(); | 178 | t = read_c0_watchhi3(); |
172 | write_c0_watchhi3(t | 0xff8); | 179 | write_c0_watchhi3(t | MIPS_WATCHHI_MASK); |
173 | back_to_back_c0_hazard(); | 180 | back_to_back_c0_hazard(); |
174 | t = read_c0_watchhi3(); | 181 | t = read_c0_watchhi3(); |
175 | c->watch_reg_masks[3] |= (t & 0xff8); | 182 | c->watch_reg_masks[3] |= (t & MIPS_WATCHHI_MASK); |
176 | if ((t & 0x80000000) == 0) | 183 | if ((t & MIPS_WATCHHI_M) == 0) |
177 | return; | 184 | return; |
178 | 185 | ||
179 | /* We use at most 4, but probe and report up to 8. */ | 186 | /* We use at most 4, but probe and report up to 8. */ |
180 | c->watch_reg_count = 5; | 187 | c->watch_reg_count = 5; |
181 | t = read_c0_watchhi4(); | 188 | t = read_c0_watchhi4(); |
182 | if ((t & 0x80000000) == 0) | 189 | if ((t & MIPS_WATCHHI_M) == 0) |
183 | return; | 190 | return; |
184 | 191 | ||
185 | c->watch_reg_count = 6; | 192 | c->watch_reg_count = 6; |
186 | t = read_c0_watchhi5(); | 193 | t = read_c0_watchhi5(); |
187 | if ((t & 0x80000000) == 0) | 194 | if ((t & MIPS_WATCHHI_M) == 0) |
188 | return; | 195 | return; |
189 | 196 | ||
190 | c->watch_reg_count = 7; | 197 | c->watch_reg_count = 7; |
191 | t = read_c0_watchhi6(); | 198 | t = read_c0_watchhi6(); |
192 | if ((t & 0x80000000) == 0) | 199 | if ((t & MIPS_WATCHHI_M) == 0) |
193 | return; | 200 | return; |
194 | 201 | ||
195 | c->watch_reg_count = 8; | 202 | c->watch_reg_count = 8; |
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index b37954cc880d..8e945e866a73 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c | |||
@@ -1068,15 +1068,15 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, | |||
1068 | kvm_read_c0_guest_ebase(cop0)); | 1068 | kvm_read_c0_guest_ebase(cop0)); |
1069 | } else if (rd == MIPS_CP0_TLB_HI && sel == 0) { | 1069 | } else if (rd == MIPS_CP0_TLB_HI && sel == 0) { |
1070 | uint32_t nasid = | 1070 | uint32_t nasid = |
1071 | vcpu->arch.gprs[rt] & ASID_MASK; | 1071 | vcpu->arch.gprs[rt] & KVM_ENTRYHI_ASID; |
1072 | if ((KSEGX(vcpu->arch.gprs[rt]) != CKSEG0) && | 1072 | if ((KSEGX(vcpu->arch.gprs[rt]) != CKSEG0) && |
1073 | ((kvm_read_c0_guest_entryhi(cop0) & | 1073 | ((kvm_read_c0_guest_entryhi(cop0) & |
1074 | ASID_MASK) != nasid)) { | 1074 | KVM_ENTRYHI_ASID) != nasid)) { |
1075 | kvm_debug("MTCz, change ASID from %#lx to %#lx\n", | 1075 | kvm_debug("MTCz, change ASID from %#lx to %#lx\n", |
1076 | kvm_read_c0_guest_entryhi(cop0) | 1076 | kvm_read_c0_guest_entryhi(cop0) |
1077 | & ASID_MASK, | 1077 | & KVM_ENTRYHI_ASID, |
1078 | vcpu->arch.gprs[rt] | 1078 | vcpu->arch.gprs[rt] |
1079 | & ASID_MASK); | 1079 | & KVM_ENTRYHI_ASID); |
1080 | 1080 | ||
1081 | /* Blow away the shadow host TLBs */ | 1081 | /* Blow away the shadow host TLBs */ |
1082 | kvm_mips_flush_host_tlb(1); | 1082 | kvm_mips_flush_host_tlb(1); |
@@ -1620,7 +1620,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, | |||
1620 | */ | 1620 | */ |
1621 | index = kvm_mips_guest_tlb_lookup(vcpu, (va & VPN2_MASK) | | 1621 | index = kvm_mips_guest_tlb_lookup(vcpu, (va & VPN2_MASK) | |
1622 | (kvm_read_c0_guest_entryhi | 1622 | (kvm_read_c0_guest_entryhi |
1623 | (cop0) & ASID_MASK)); | 1623 | (cop0) & KVM_ENTRYHI_ASID)); |
1624 | 1624 | ||
1625 | if (index < 0) { | 1625 | if (index < 0) { |
1626 | vcpu->arch.host_cp0_entryhi = (va & VPN2_MASK); | 1626 | vcpu->arch.host_cp0_entryhi = (va & VPN2_MASK); |
@@ -1786,7 +1786,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_ld(unsigned long cause, | |||
1786 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 1786 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
1787 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1787 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1788 | unsigned long entryhi = (vcpu->arch. host_cp0_badvaddr & VPN2_MASK) | | 1788 | unsigned long entryhi = (vcpu->arch. host_cp0_badvaddr & VPN2_MASK) | |
1789 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1789 | (kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID); |
1790 | 1790 | ||
1791 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 1791 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
1792 | /* save old pc */ | 1792 | /* save old pc */ |
@@ -1833,7 +1833,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_ld(unsigned long cause, | |||
1833 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1833 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1834 | unsigned long entryhi = | 1834 | unsigned long entryhi = |
1835 | (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1835 | (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1836 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1836 | (kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID); |
1837 | 1837 | ||
1838 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 1838 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
1839 | /* save old pc */ | 1839 | /* save old pc */ |
@@ -1878,7 +1878,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_st(unsigned long cause, | |||
1878 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 1878 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
1879 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1879 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1880 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1880 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1881 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1881 | (kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID); |
1882 | 1882 | ||
1883 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 1883 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
1884 | /* save old pc */ | 1884 | /* save old pc */ |
@@ -1922,7 +1922,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_st(unsigned long cause, | |||
1922 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 1922 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
1923 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1923 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1924 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1924 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1925 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1925 | (kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID); |
1926 | 1926 | ||
1927 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 1927 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
1928 | /* save old pc */ | 1928 | /* save old pc */ |
@@ -1967,7 +1967,7 @@ enum emulation_result kvm_mips_handle_tlbmod(unsigned long cause, uint32_t *opc, | |||
1967 | #ifdef DEBUG | 1967 | #ifdef DEBUG |
1968 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 1968 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
1969 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1969 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1970 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1970 | (kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID); |
1971 | int index; | 1971 | int index; |
1972 | 1972 | ||
1973 | /* If address not in the guest TLB, then we are in trouble */ | 1973 | /* If address not in the guest TLB, then we are in trouble */ |
@@ -1994,7 +1994,7 @@ enum emulation_result kvm_mips_emulate_tlbmod(unsigned long cause, | |||
1994 | { | 1994 | { |
1995 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 1995 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
1996 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1996 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1997 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1997 | (kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID); |
1998 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1998 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1999 | 1999 | ||
2000 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 2000 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
@@ -2569,7 +2569,8 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause, | |||
2569 | */ | 2569 | */ |
2570 | index = kvm_mips_guest_tlb_lookup(vcpu, | 2570 | index = kvm_mips_guest_tlb_lookup(vcpu, |
2571 | (va & VPN2_MASK) | | 2571 | (va & VPN2_MASK) | |
2572 | (kvm_read_c0_guest_entryhi(vcpu->arch.cop0) & ASID_MASK)); | 2572 | (kvm_read_c0_guest_entryhi(vcpu->arch.cop0) & |
2573 | KVM_ENTRYHI_ASID)); | ||
2573 | if (index < 0) { | 2574 | if (index < 0) { |
2574 | if (exccode == EXCCODE_TLBL) { | 2575 | if (exccode == EXCCODE_TLBL) { |
2575 | er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu); | 2576 | er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu); |
diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S index 81687ab1b523..3ef03009de5f 100644 --- a/arch/mips/kvm/locore.S +++ b/arch/mips/kvm/locore.S | |||
@@ -32,7 +32,6 @@ | |||
32 | EXPORT(x); | 32 | EXPORT(x); |
33 | 33 | ||
34 | /* Overload, Danger Will Robinson!! */ | 34 | /* Overload, Danger Will Robinson!! */ |
35 | #define PT_HOST_ASID PT_BVADDR | ||
36 | #define PT_HOST_USERLOCAL PT_EPC | 35 | #define PT_HOST_USERLOCAL PT_EPC |
37 | 36 | ||
38 | #define CP0_DDATA_LO $28,3 | 37 | #define CP0_DDATA_LO $28,3 |
@@ -49,45 +48,18 @@ | |||
49 | * a1: vcpu | 48 | * a1: vcpu |
50 | */ | 49 | */ |
51 | .set noreorder | 50 | .set noreorder |
52 | .set noat | ||
53 | 51 | ||
54 | FEXPORT(__kvm_mips_vcpu_run) | 52 | FEXPORT(__kvm_mips_vcpu_run) |
55 | /* k0/k1 not being used in host kernel context */ | 53 | /* k0/k1 not being used in host kernel context */ |
56 | INT_ADDIU k1, sp, -PT_SIZE | 54 | INT_ADDIU k1, sp, -PT_SIZE |
57 | LONG_S $0, PT_R0(k1) | ||
58 | LONG_S $1, PT_R1(k1) | ||
59 | LONG_S $2, PT_R2(k1) | ||
60 | LONG_S $3, PT_R3(k1) | ||
61 | |||
62 | LONG_S $4, PT_R4(k1) | ||
63 | LONG_S $5, PT_R5(k1) | ||
64 | LONG_S $6, PT_R6(k1) | ||
65 | LONG_S $7, PT_R7(k1) | ||
66 | |||
67 | LONG_S $8, PT_R8(k1) | ||
68 | LONG_S $9, PT_R9(k1) | ||
69 | LONG_S $10, PT_R10(k1) | ||
70 | LONG_S $11, PT_R11(k1) | ||
71 | LONG_S $12, PT_R12(k1) | ||
72 | LONG_S $13, PT_R13(k1) | ||
73 | LONG_S $14, PT_R14(k1) | ||
74 | LONG_S $15, PT_R15(k1) | ||
75 | LONG_S $16, PT_R16(k1) | 55 | LONG_S $16, PT_R16(k1) |
76 | LONG_S $17, PT_R17(k1) | 56 | LONG_S $17, PT_R17(k1) |
77 | |||
78 | LONG_S $18, PT_R18(k1) | 57 | LONG_S $18, PT_R18(k1) |
79 | LONG_S $19, PT_R19(k1) | 58 | LONG_S $19, PT_R19(k1) |
80 | LONG_S $20, PT_R20(k1) | 59 | LONG_S $20, PT_R20(k1) |
81 | LONG_S $21, PT_R21(k1) | 60 | LONG_S $21, PT_R21(k1) |
82 | LONG_S $22, PT_R22(k1) | 61 | LONG_S $22, PT_R22(k1) |
83 | LONG_S $23, PT_R23(k1) | 62 | LONG_S $23, PT_R23(k1) |
84 | LONG_S $24, PT_R24(k1) | ||
85 | LONG_S $25, PT_R25(k1) | ||
86 | |||
87 | /* | ||
88 | * XXXKYMA k0/k1 not saved, not being used if we got here through | ||
89 | * an ioctl() | ||
90 | */ | ||
91 | 63 | ||
92 | LONG_S $28, PT_R28(k1) | 64 | LONG_S $28, PT_R28(k1) |
93 | LONG_S $29, PT_R29(k1) | 65 | LONG_S $29, PT_R29(k1) |
@@ -104,11 +76,6 @@ FEXPORT(__kvm_mips_vcpu_run) | |||
104 | mfc0 v0, CP0_STATUS | 76 | mfc0 v0, CP0_STATUS |
105 | LONG_S v0, PT_STATUS(k1) | 77 | LONG_S v0, PT_STATUS(k1) |
106 | 78 | ||
107 | /* Save host ASID, shove it into the BVADDR location */ | ||
108 | mfc0 v1, CP0_ENTRYHI | ||
109 | andi v1, 0xff | ||
110 | LONG_S v1, PT_HOST_ASID(k1) | ||
111 | |||
112 | /* Save DDATA_LO, will be used to store pointer to vcpu */ | 79 | /* Save DDATA_LO, will be used to store pointer to vcpu */ |
113 | mfc0 v1, CP0_DDATA_LO | 80 | mfc0 v1, CP0_DDATA_LO |
114 | LONG_S v1, PT_HOST_USERLOCAL(k1) | 81 | LONG_S v1, PT_HOST_USERLOCAL(k1) |
@@ -170,13 +137,21 @@ FEXPORT(__kvm_mips_load_asid) | |||
170 | INT_SLL t2, t2, 2 /* x4 */ | 137 | INT_SLL t2, t2, 2 /* x4 */ |
171 | REG_ADDU t3, t1, t2 | 138 | REG_ADDU t3, t1, t2 |
172 | LONG_L k0, (t3) | 139 | LONG_L k0, (t3) |
173 | andi k0, k0, 0xff | 140 | #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE |
141 | li t3, CPUINFO_SIZE/4 | ||
142 | mul t2, t2, t3 /* x sizeof(struct cpuinfo_mips)/4 */ | ||
143 | LONG_L t2, (cpu_data + CPUINFO_ASID_MASK)(t2) | ||
144 | and k0, k0, t2 | ||
145 | #else | ||
146 | andi k0, k0, MIPS_ENTRYHI_ASID | ||
147 | #endif | ||
174 | mtc0 k0, CP0_ENTRYHI | 148 | mtc0 k0, CP0_ENTRYHI |
175 | ehb | 149 | ehb |
176 | 150 | ||
177 | /* Disable RDHWR access */ | 151 | /* Disable RDHWR access */ |
178 | mtc0 zero, CP0_HWRENA | 152 | mtc0 zero, CP0_HWRENA |
179 | 153 | ||
154 | .set noat | ||
180 | /* Now load up the Guest Context from VCPU */ | 155 | /* Now load up the Guest Context from VCPU */ |
181 | LONG_L $1, VCPU_R1(k1) | 156 | LONG_L $1, VCPU_R1(k1) |
182 | LONG_L $2, VCPU_R2(k1) | 157 | LONG_L $2, VCPU_R2(k1) |
@@ -288,6 +263,8 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | |||
288 | LONG_S $30, VCPU_R30(k1) | 263 | LONG_S $30, VCPU_R30(k1) |
289 | LONG_S $31, VCPU_R31(k1) | 264 | LONG_S $31, VCPU_R31(k1) |
290 | 265 | ||
266 | .set at | ||
267 | |||
291 | /* We need to save hi/lo and restore them on the way out */ | 268 | /* We need to save hi/lo and restore them on the way out */ |
292 | mfhi t0 | 269 | mfhi t0 |
293 | LONG_S t0, VCPU_HI(k1) | 270 | LONG_S t0, VCPU_HI(k1) |
@@ -339,9 +316,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | |||
339 | /* load up the host EBASE */ | 316 | /* load up the host EBASE */ |
340 | mfc0 v0, CP0_STATUS | 317 | mfc0 v0, CP0_STATUS |
341 | 318 | ||
342 | .set at | ||
343 | or k0, v0, ST0_BEV | 319 | or k0, v0, ST0_BEV |
344 | .set noat | ||
345 | 320 | ||
346 | mtc0 k0, CP0_STATUS | 321 | mtc0 k0, CP0_STATUS |
347 | ehb | 322 | ehb |
@@ -353,7 +328,6 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | |||
353 | * If FPU is enabled, save FCR31 and clear it so that later ctc1's don't | 328 | * If FPU is enabled, save FCR31 and clear it so that later ctc1's don't |
354 | * trigger FPE for pending exceptions. | 329 | * trigger FPE for pending exceptions. |
355 | */ | 330 | */ |
356 | .set at | ||
357 | and v1, v0, ST0_CU1 | 331 | and v1, v0, ST0_CU1 |
358 | beqz v1, 1f | 332 | beqz v1, 1f |
359 | nop | 333 | nop |
@@ -363,7 +337,6 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | |||
363 | sw t0, VCPU_FCR31(k1) | 337 | sw t0, VCPU_FCR31(k1) |
364 | ctc1 zero,fcr31 | 338 | ctc1 zero,fcr31 |
365 | .set pop | 339 | .set pop |
366 | .set noat | ||
367 | 1: | 340 | 1: |
368 | 341 | ||
369 | #ifdef CONFIG_CPU_HAS_MSA | 342 | #ifdef CONFIG_CPU_HAS_MSA |
@@ -386,10 +359,8 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | |||
386 | #endif | 359 | #endif |
387 | 360 | ||
388 | /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ | 361 | /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ |
389 | .set at | ||
390 | and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) | 362 | and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) |
391 | or v0, v0, ST0_CU0 | 363 | or v0, v0, ST0_CU0 |
392 | .set noat | ||
393 | mtc0 v0, CP0_STATUS | 364 | mtc0 v0, CP0_STATUS |
394 | ehb | 365 | ehb |
395 | 366 | ||
@@ -456,18 +427,14 @@ __kvm_mips_return_to_guest: | |||
456 | 427 | ||
457 | /* Switch EBASE back to the one used by KVM */ | 428 | /* Switch EBASE back to the one used by KVM */ |
458 | mfc0 v1, CP0_STATUS | 429 | mfc0 v1, CP0_STATUS |
459 | .set at | ||
460 | or k0, v1, ST0_BEV | 430 | or k0, v1, ST0_BEV |
461 | .set noat | ||
462 | mtc0 k0, CP0_STATUS | 431 | mtc0 k0, CP0_STATUS |
463 | ehb | 432 | ehb |
464 | mtc0 t0, CP0_EBASE | 433 | mtc0 t0, CP0_EBASE |
465 | 434 | ||
466 | /* Setup status register for running guest in UM */ | 435 | /* Setup status register for running guest in UM */ |
467 | .set at | ||
468 | or v1, v1, (ST0_EXL | KSU_USER | ST0_IE) | 436 | or v1, v1, (ST0_EXL | KSU_USER | ST0_IE) |
469 | and v1, v1, ~(ST0_CU0 | ST0_MX) | 437 | and v1, v1, ~(ST0_CU0 | ST0_MX) |
470 | .set noat | ||
471 | mtc0 v1, CP0_STATUS | 438 | mtc0 v1, CP0_STATUS |
472 | ehb | 439 | ehb |
473 | 440 | ||
@@ -489,13 +456,21 @@ __kvm_mips_return_to_guest: | |||
489 | INT_SLL t2, t2, 2 /* x4 */ | 456 | INT_SLL t2, t2, 2 /* x4 */ |
490 | REG_ADDU t3, t1, t2 | 457 | REG_ADDU t3, t1, t2 |
491 | LONG_L k0, (t3) | 458 | LONG_L k0, (t3) |
492 | andi k0, k0, 0xff | 459 | #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE |
460 | li t3, CPUINFO_SIZE/4 | ||
461 | mul t2, t2, t3 /* x sizeof(struct cpuinfo_mips)/4 */ | ||
462 | LONG_L t2, (cpu_data + CPUINFO_ASID_MASK)(t2) | ||
463 | and k0, k0, t2 | ||
464 | #else | ||
465 | andi k0, k0, MIPS_ENTRYHI_ASID | ||
466 | #endif | ||
493 | mtc0 k0, CP0_ENTRYHI | 467 | mtc0 k0, CP0_ENTRYHI |
494 | ehb | 468 | ehb |
495 | 469 | ||
496 | /* Disable RDHWR access */ | 470 | /* Disable RDHWR access */ |
497 | mtc0 zero, CP0_HWRENA | 471 | mtc0 zero, CP0_HWRENA |
498 | 472 | ||
473 | .set noat | ||
499 | /* load the guest context from VCPU and return */ | 474 | /* load the guest context from VCPU and return */ |
500 | LONG_L $0, VCPU_R0(k1) | 475 | LONG_L $0, VCPU_R0(k1) |
501 | LONG_L $1, VCPU_R1(k1) | 476 | LONG_L $1, VCPU_R1(k1) |
@@ -541,6 +516,7 @@ FEXPORT(__kvm_mips_skip_guest_restore) | |||
541 | LONG_L k1, VCPU_R27(k1) | 516 | LONG_L k1, VCPU_R27(k1) |
542 | 517 | ||
543 | eret | 518 | eret |
519 | .set at | ||
544 | 520 | ||
545 | __kvm_mips_return_to_host: | 521 | __kvm_mips_return_to_host: |
546 | /* EBASE is already pointing to Linux */ | 522 | /* EBASE is already pointing to Linux */ |
@@ -551,16 +527,6 @@ __kvm_mips_return_to_host: | |||
551 | LONG_L k0, PT_HOST_USERLOCAL(k1) | 527 | LONG_L k0, PT_HOST_USERLOCAL(k1) |
552 | mtc0 k0, CP0_DDATA_LO | 528 | mtc0 k0, CP0_DDATA_LO |
553 | 529 | ||
554 | /* Restore host ASID */ | ||
555 | LONG_L k0, PT_HOST_ASID(sp) | ||
556 | andi k0, 0xff | ||
557 | mtc0 k0,CP0_ENTRYHI | ||
558 | ehb | ||
559 | |||
560 | /* Load context saved on the host stack */ | ||
561 | LONG_L $0, PT_R0(k1) | ||
562 | LONG_L $1, PT_R1(k1) | ||
563 | |||
564 | /* | 530 | /* |
565 | * r2/v0 is the return code, shift it down by 2 (arithmetic) | 531 | * r2/v0 is the return code, shift it down by 2 (arithmetic) |
566 | * to recover the err code | 532 | * to recover the err code |
@@ -568,19 +534,7 @@ __kvm_mips_return_to_host: | |||
568 | INT_SRA k0, v0, 2 | 534 | INT_SRA k0, v0, 2 |
569 | move $2, k0 | 535 | move $2, k0 |
570 | 536 | ||
571 | LONG_L $3, PT_R3(k1) | 537 | /* Load context saved on the host stack */ |
572 | LONG_L $4, PT_R4(k1) | ||
573 | LONG_L $5, PT_R5(k1) | ||
574 | LONG_L $6, PT_R6(k1) | ||
575 | LONG_L $7, PT_R7(k1) | ||
576 | LONG_L $8, PT_R8(k1) | ||
577 | LONG_L $9, PT_R9(k1) | ||
578 | LONG_L $10, PT_R10(k1) | ||
579 | LONG_L $11, PT_R11(k1) | ||
580 | LONG_L $12, PT_R12(k1) | ||
581 | LONG_L $13, PT_R13(k1) | ||
582 | LONG_L $14, PT_R14(k1) | ||
583 | LONG_L $15, PT_R15(k1) | ||
584 | LONG_L $16, PT_R16(k1) | 538 | LONG_L $16, PT_R16(k1) |
585 | LONG_L $17, PT_R17(k1) | 539 | LONG_L $17, PT_R17(k1) |
586 | LONG_L $18, PT_R18(k1) | 540 | LONG_L $18, PT_R18(k1) |
@@ -589,10 +543,6 @@ __kvm_mips_return_to_host: | |||
589 | LONG_L $21, PT_R21(k1) | 543 | LONG_L $21, PT_R21(k1) |
590 | LONG_L $22, PT_R22(k1) | 544 | LONG_L $22, PT_R22(k1) |
591 | LONG_L $23, PT_R23(k1) | 545 | LONG_L $23, PT_R23(k1) |
592 | LONG_L $24, PT_R24(k1) | ||
593 | LONG_L $25, PT_R25(k1) | ||
594 | |||
595 | /* Host k0/k1 were not saved */ | ||
596 | 546 | ||
597 | LONG_L $28, PT_R28(k1) | 547 | LONG_L $28, PT_R28(k1) |
598 | LONG_L $29, PT_R29(k1) | 548 | LONG_L $29, PT_R29(k1) |
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c index e0e1d0a611fc..b9c52c1d35d6 100644 --- a/arch/mips/kvm/tlb.c +++ b/arch/mips/kvm/tlb.c | |||
@@ -49,12 +49,18 @@ EXPORT_SYMBOL_GPL(kvm_mips_is_error_pfn); | |||
49 | 49 | ||
50 | uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) | 50 | uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) |
51 | { | 51 | { |
52 | return vcpu->arch.guest_kernel_asid[smp_processor_id()] & ASID_MASK; | 52 | int cpu = smp_processor_id(); |
53 | |||
54 | return vcpu->arch.guest_kernel_asid[cpu] & | ||
55 | cpu_asid_mask(&cpu_data[cpu]); | ||
53 | } | 56 | } |
54 | 57 | ||
55 | uint32_t kvm_mips_get_user_asid(struct kvm_vcpu *vcpu) | 58 | uint32_t kvm_mips_get_user_asid(struct kvm_vcpu *vcpu) |
56 | { | 59 | { |
57 | return vcpu->arch.guest_user_asid[smp_processor_id()] & ASID_MASK; | 60 | int cpu = smp_processor_id(); |
61 | |||
62 | return vcpu->arch.guest_user_asid[cpu] & | ||
63 | cpu_asid_mask(&cpu_data[cpu]); | ||
58 | } | 64 | } |
59 | 65 | ||
60 | inline uint32_t kvm_mips_get_commpage_asid(struct kvm_vcpu *vcpu) | 66 | inline uint32_t kvm_mips_get_commpage_asid(struct kvm_vcpu *vcpu) |
@@ -78,7 +84,8 @@ void kvm_mips_dump_host_tlbs(void) | |||
78 | old_pagemask = read_c0_pagemask(); | 84 | old_pagemask = read_c0_pagemask(); |
79 | 85 | ||
80 | kvm_info("HOST TLBs:\n"); | 86 | kvm_info("HOST TLBs:\n"); |
81 | kvm_info("ASID: %#lx\n", read_c0_entryhi() & ASID_MASK); | 87 | kvm_info("ASID: %#lx\n", read_c0_entryhi() & |
88 | cpu_asid_mask(¤t_cpu_data)); | ||
82 | 89 | ||
83 | for (i = 0; i < current_cpu_data.tlbsize; i++) { | 90 | for (i = 0; i < current_cpu_data.tlbsize; i++) { |
84 | write_c0_index(i); | 91 | write_c0_index(i); |
@@ -564,15 +571,15 @@ void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu, | |||
564 | { | 571 | { |
565 | unsigned long asid = asid_cache(cpu); | 572 | unsigned long asid = asid_cache(cpu); |
566 | 573 | ||
567 | asid += ASID_INC; | 574 | asid += cpu_asid_inc(); |
568 | if (!(asid & ASID_MASK)) { | 575 | if (!(asid & cpu_asid_mask(&cpu_data[cpu]))) { |
569 | if (cpu_has_vtag_icache) | 576 | if (cpu_has_vtag_icache) |
570 | flush_icache_all(); | 577 | flush_icache_all(); |
571 | 578 | ||
572 | kvm_local_flush_tlb_all(); /* start new asid cycle */ | 579 | kvm_local_flush_tlb_all(); /* start new asid cycle */ |
573 | 580 | ||
574 | if (!asid) /* fix version if needed */ | 581 | if (!asid) /* fix version if needed */ |
575 | asid = ASID_FIRST_VERSION; | 582 | asid = asid_first_version(cpu); |
576 | } | 583 | } |
577 | 584 | ||
578 | cpu_context(cpu, mm) = asid_cache(cpu) = asid; | 585 | cpu_context(cpu, mm) = asid_cache(cpu) = asid; |
@@ -627,6 +634,7 @@ static void kvm_mips_migrate_count(struct kvm_vcpu *vcpu) | |||
627 | /* Restore ASID once we are scheduled back after preemption */ | 634 | /* Restore ASID once we are scheduled back after preemption */ |
628 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 635 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
629 | { | 636 | { |
637 | unsigned long asid_mask = cpu_asid_mask(&cpu_data[cpu]); | ||
630 | unsigned long flags; | 638 | unsigned long flags; |
631 | int newasid = 0; | 639 | int newasid = 0; |
632 | 640 | ||
@@ -637,7 +645,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
637 | local_irq_save(flags); | 645 | local_irq_save(flags); |
638 | 646 | ||
639 | if ((vcpu->arch.guest_kernel_asid[cpu] ^ asid_cache(cpu)) & | 647 | if ((vcpu->arch.guest_kernel_asid[cpu] ^ asid_cache(cpu)) & |
640 | ASID_VERSION_MASK) { | 648 | asid_version_mask(cpu)) { |
641 | kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu); | 649 | kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu); |
642 | vcpu->arch.guest_kernel_asid[cpu] = | 650 | vcpu->arch.guest_kernel_asid[cpu] = |
643 | vcpu->arch.guest_kernel_mm.context.asid[cpu]; | 651 | vcpu->arch.guest_kernel_mm.context.asid[cpu]; |
@@ -672,7 +680,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
672 | */ | 680 | */ |
673 | if (current->flags & PF_VCPU) { | 681 | if (current->flags & PF_VCPU) { |
674 | write_c0_entryhi(vcpu->arch. | 682 | write_c0_entryhi(vcpu->arch. |
675 | preempt_entryhi & ASID_MASK); | 683 | preempt_entryhi & asid_mask); |
676 | ehb(); | 684 | ehb(); |
677 | } | 685 | } |
678 | } else { | 686 | } else { |
@@ -687,11 +695,11 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
687 | if (KVM_GUEST_KERNEL_MODE(vcpu)) | 695 | if (KVM_GUEST_KERNEL_MODE(vcpu)) |
688 | write_c0_entryhi(vcpu->arch. | 696 | write_c0_entryhi(vcpu->arch. |
689 | guest_kernel_asid[cpu] & | 697 | guest_kernel_asid[cpu] & |
690 | ASID_MASK); | 698 | asid_mask); |
691 | else | 699 | else |
692 | write_c0_entryhi(vcpu->arch. | 700 | write_c0_entryhi(vcpu->arch. |
693 | guest_user_asid[cpu] & | 701 | guest_user_asid[cpu] & |
694 | ASID_MASK); | 702 | asid_mask); |
695 | ehb(); | 703 | ehb(); |
696 | } | 704 | } |
697 | } | 705 | } |
@@ -721,7 +729,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
721 | kvm_mips_callbacks->vcpu_get_regs(vcpu); | 729 | kvm_mips_callbacks->vcpu_get_regs(vcpu); |
722 | 730 | ||
723 | if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) & | 731 | if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) & |
724 | ASID_VERSION_MASK)) { | 732 | asid_version_mask(cpu))) { |
725 | kvm_debug("%s: Dropping MMU Context: %#lx\n", __func__, | 733 | kvm_debug("%s: Dropping MMU Context: %#lx\n", __func__, |
726 | cpu_context(cpu, current->mm)); | 734 | cpu_context(cpu, current->mm)); |
727 | drop_mmu_context(current->mm, cpu); | 735 | drop_mmu_context(current->mm, cpu); |
@@ -748,7 +756,8 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu) | |||
748 | inst = *(opc); | 756 | inst = *(opc); |
749 | } else { | 757 | } else { |
750 | vpn2 = (unsigned long) opc & VPN2_MASK; | 758 | vpn2 = (unsigned long) opc & VPN2_MASK; |
751 | asid = kvm_read_c0_guest_entryhi(cop0) & ASID_MASK; | 759 | asid = kvm_read_c0_guest_entryhi(cop0) & |
760 | KVM_ENTRYHI_ASID; | ||
752 | index = kvm_mips_guest_tlb_lookup(vcpu, vpn2 | asid); | 761 | index = kvm_mips_guest_tlb_lookup(vcpu, vpn2 | asid); |
753 | if (index < 0) { | 762 | if (index < 0) { |
754 | kvm_err("%s: get_user_failed for %p, vcpu: %p, ASID: %#lx\n", | 763 | kvm_err("%s: get_user_failed for %p, vcpu: %p, ASID: %#lx\n", |
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index c4038d2a724c..fd43f0afdb9f 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c | |||
@@ -505,7 +505,8 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu) | |||
505 | kvm_write_c0_guest_intctl(cop0, 0xFC000000); | 505 | kvm_write_c0_guest_intctl(cop0, 0xFC000000); |
506 | 506 | ||
507 | /* Put in vcpu id as CPUNum into Ebase Reg to handle SMP Guests */ | 507 | /* Put in vcpu id as CPUNum into Ebase Reg to handle SMP Guests */ |
508 | kvm_write_c0_guest_ebase(cop0, KVM_GUEST_KSEG0 | (vcpu_id & 0xFF)); | 508 | kvm_write_c0_guest_ebase(cop0, KVM_GUEST_KSEG0 | |
509 | (vcpu_id & MIPS_EBASE_CPUNUM)); | ||
509 | 510 | ||
510 | return 0; | 511 | return 0; |
511 | } | 512 | } |
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index e10d33342b30..177769dbb0e8 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig | |||
@@ -25,7 +25,17 @@ config SOC_FALCON | |||
25 | endchoice | 25 | endchoice |
26 | 26 | ||
27 | choice | 27 | choice |
28 | prompt "Devicetree" | 28 | prompt "Built-in device tree" |
29 | help | ||
30 | Legacy bootloaders do not pass a DTB pointer to the kernel, so | ||
31 | if a "wrapper" is not being used, the kernel will need to include | ||
32 | a device tree that matches the target board. | ||
33 | |||
34 | The builtin DTB will only be used if the firmware does not supply | ||
35 | a valid DTB. | ||
36 | |||
37 | config LANTIQ_DT_NONE | ||
38 | bool "None" | ||
29 | 39 | ||
30 | config DT_EASY50712 | 40 | config DT_EASY50712 |
31 | bool "Easy50712" | 41 | bool "Easy50712" |
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile index 690257ab86d6..2718652e7466 100644 --- a/arch/mips/lantiq/Makefile +++ b/arch/mips/lantiq/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 1 | # Copyright (C) 2010 John Crispin <john@phrozen.org> |
2 | # | 2 | # |
3 | # This program is free software; you can redistribute it and/or modify it | 3 | # This program is free software; you can redistribute it and/or modify it |
4 | # under the terms of the GNU General Public License version 2 as published | 4 | # under the terms of the GNU General Public License version 2 as published |
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c index a0706fd4ce0a..149f0513c4f5 100644 --- a/arch/mips/lantiq/clk.c +++ b/arch/mips/lantiq/clk.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> | 6 | * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> |
7 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | #include <linux/io.h> | 9 | #include <linux/io.h> |
10 | #include <linux/export.h> | 10 | #include <linux/export.h> |
diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h index 7376ce817eda..e806e048ffc2 100644 --- a/arch/mips/lantiq/clk.h +++ b/arch/mips/lantiq/clk.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _LTQ_CLK_H__ | 9 | #ifndef _LTQ_CLK_H__ |
diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c index 9b28d0940ef4..44bccaee822b 100644 --- a/arch/mips/lantiq/early_printk.c +++ b/arch/mips/lantiq/early_printk.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/cpu.h> | 9 | #include <linux/cpu.h> |
diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c index aa9497947859..75315c0a9fc3 100644 --- a/arch/mips/lantiq/falcon/prom.c +++ b/arch/mips/lantiq/falcon/prom.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com> | 6 | * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com> |
7 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c index 568248253426..7a535d72f541 100644 --- a/arch/mips/lantiq/falcon/reset.c +++ b/arch/mips/lantiq/falcon/reset.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com> | 6 | * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com> |
7 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c index 7edcd4946fc1..2a1b3021589c 100644 --- a/arch/mips/lantiq/falcon/sysctrl.c +++ b/arch/mips/lantiq/falcon/sysctrl.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com> | 6 | * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com> |
7 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2011 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/ioport.h> | 10 | #include <linux/ioport.h> |
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index 2e7f60c9fc5d..ff17669e30a3 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> | 7 | * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> |
8 | */ | 8 | */ |
9 | 9 | ||
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 297bcaa6b5d3..5f693ac77a0d 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/export.h> | 9 | #include <linux/export.h> |
@@ -65,6 +65,8 @@ static void __init prom_init_cmdline(void) | |||
65 | 65 | ||
66 | void __init plat_mem_setup(void) | 66 | void __init plat_mem_setup(void) |
67 | { | 67 | { |
68 | void *dtb; | ||
69 | |||
68 | ioport_resource.start = IOPORT_RESOURCE_START; | 70 | ioport_resource.start = IOPORT_RESOURCE_START; |
69 | ioport_resource.end = IOPORT_RESOURCE_END; | 71 | ioport_resource.end = IOPORT_RESOURCE_END; |
70 | iomem_resource.start = IOMEM_RESOURCE_START; | 72 | iomem_resource.start = IOMEM_RESOURCE_START; |
@@ -72,11 +74,18 @@ void __init plat_mem_setup(void) | |||
72 | 74 | ||
73 | set_io_port_base((unsigned long) KSEG1); | 75 | set_io_port_base((unsigned long) KSEG1); |
74 | 76 | ||
77 | if (fw_arg0 == -2) /* UHI interface */ | ||
78 | dtb = (void *)fw_arg1; | ||
79 | else if (__dtb_start != __dtb_end) | ||
80 | dtb = (void *)__dtb_start; | ||
81 | else | ||
82 | panic("no dtb found"); | ||
83 | |||
75 | /* | 84 | /* |
76 | * Load the builtin devicetree. This causes the chosen node to be | 85 | * Load the devicetree. This causes the chosen node to be |
77 | * parsed resulting in our memory appearing | 86 | * parsed resulting in our memory appearing |
78 | */ | 87 | */ |
79 | __dt_setup_arch(__dtb_start); | 88 | __dt_setup_arch(dtb); |
80 | } | 89 | } |
81 | 90 | ||
82 | void __init device_tree_init(void) | 91 | void __init device_tree_init(void) |
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h index bfd2d58c1d69..4b6576c50250 100644 --- a/arch/mips/lantiq/prom.h +++ b/arch/mips/lantiq/prom.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _LTQ_PROM_H__ | 9 | #ifndef _LTQ_PROM_H__ |
diff --git a/arch/mips/lantiq/xway/clk.c b/arch/mips/lantiq/xway/clk.c index 07f6d5b0b65e..41fc30d8ef89 100644 --- a/arch/mips/lantiq/xway/clk.c +++ b/arch/mips/lantiq/xway/clk.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | 7 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG |
8 | */ | 8 | */ |
9 | 9 | ||
diff --git a/arch/mips/lantiq/xway/dcdc.c b/arch/mips/lantiq/xway/dcdc.c index ae8e930f5283..08f7abaadfe5 100644 --- a/arch/mips/lantiq/xway/dcdc.c +++ b/arch/mips/lantiq/xway/dcdc.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
7 | * Copyright (C) 2010 Sameer Ahmad, Lantiq GmbH | 7 | * Copyright (C) 2010 Sameer Ahmad, Lantiq GmbH |
8 | */ | 8 | */ |
9 | 9 | ||
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index 34a116e840d8..cef811755123 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * along with this program; if not, write to the Free Software | 12 | * along with this program; if not, write to the Free Software |
13 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 13 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
14 | * | 14 | * |
15 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | 15 | * Copyright (C) 2011 John Crispin <john@phrozen.org> |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
diff --git a/arch/mips/lantiq/xway/gptu.c b/arch/mips/lantiq/xway/gptu.c index f1492b2db017..0f1bbea1a816 100644 --- a/arch/mips/lantiq/xway/gptu.c +++ b/arch/mips/lantiq/xway/gptu.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
7 | * Copyright (C) 2012 Lantiq GmbH | 7 | * Copyright (C) 2012 Lantiq GmbH |
8 | */ | 8 | */ |
9 | 9 | ||
diff --git a/arch/mips/lantiq/xway/prom.c b/arch/mips/lantiq/xway/prom.c index 8f6e02f1e965..9475b2510adb 100644 --- a/arch/mips/lantiq/xway/prom.c +++ b/arch/mips/lantiq/xway/prom.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | 7 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG |
8 | */ | 8 | */ |
9 | 9 | ||
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index bc29bb349e94..83fd65d76e81 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | 7 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -258,7 +258,7 @@ static int ltq_reset_device(struct reset_controller_dev *rcdev, | |||
258 | return ltq_deassert_device(rcdev, id); | 258 | return ltq_deassert_device(rcdev, id); |
259 | } | 259 | } |
260 | 260 | ||
261 | static struct reset_control_ops reset_ops = { | 261 | static const struct reset_control_ops reset_ops = { |
262 | .reset = ltq_reset_device, | 262 | .reset = ltq_reset_device, |
263 | .assert = ltq_assert_device, | 263 | .assert = ltq_assert_device, |
264 | .deassert = ltq_deassert_device, | 264 | .deassert = ltq_deassert_device, |
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 80554e8f6037..236193b5210b 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2011-2012 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2011-2012 John Crispin <john@phrozen.org> |
7 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | 7 | * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG |
8 | */ | 8 | */ |
9 | 9 | ||
diff --git a/arch/mips/lantiq/xway/vmmc.c b/arch/mips/lantiq/xway/vmmc.c index d001bc38908a..4625495f9230 100644 --- a/arch/mips/lantiq/xway/vmmc.c +++ b/arch/mips/lantiq/xway/vmmc.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c index 199094a40c15..71e518c1e7e7 100644 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
@@ -112,6 +112,6 @@ static struct platform_driver xway_phy_driver = { | |||
112 | 112 | ||
113 | module_platform_driver(xway_phy_driver); | 113 | module_platform_driver(xway_phy_driver); |
114 | 114 | ||
115 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); | 115 | MODULE_AUTHOR("John Crispin <john@phrozen.org>"); |
116 | MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader"); | 116 | MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader"); |
117 | MODULE_LICENSE("GPL"); | 117 | MODULE_LICENSE("GPL"); |
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 92a37319efbe..0f80b936e75e 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c | |||
@@ -19,6 +19,8 @@ void dump_tlb_regs(void) | |||
19 | 19 | ||
20 | pr_info("Index : %0x\n", read_c0_index()); | 20 | pr_info("Index : %0x\n", read_c0_index()); |
21 | pr_info("PageMask : %0x\n", read_c0_pagemask()); | 21 | pr_info("PageMask : %0x\n", read_c0_pagemask()); |
22 | if (cpu_has_guestid) | ||
23 | pr_info("GuestCtl1: %0x\n", read_c0_guestctl1()); | ||
22 | pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi()); | 24 | pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi()); |
23 | pr_info("EntryLo0 : %0*lx\n", field, read_c0_entrylo0()); | 25 | pr_info("EntryLo0 : %0*lx\n", field, read_c0_entrylo0()); |
24 | pr_info("EntryLo1 : %0*lx\n", field, read_c0_entrylo1()); | 26 | pr_info("EntryLo1 : %0*lx\n", field, read_c0_entrylo1()); |
@@ -72,7 +74,10 @@ static void dump_tlb(int first, int last) | |||
72 | { | 74 | { |
73 | unsigned long s_entryhi, entryhi, asid; | 75 | unsigned long s_entryhi, entryhi, asid; |
74 | unsigned long long entrylo0, entrylo1, pa; | 76 | unsigned long long entrylo0, entrylo1, pa; |
75 | unsigned int s_index, s_pagemask, pagemask, c0, c1, i; | 77 | unsigned int s_index, s_pagemask, s_guestctl1 = 0; |
78 | unsigned int pagemask, guestctl1 = 0, c0, c1, i; | ||
79 | unsigned long asidmask = cpu_asid_mask(¤t_cpu_data); | ||
80 | int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4); | ||
76 | #ifdef CONFIG_32BIT | 81 | #ifdef CONFIG_32BIT |
77 | bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA); | 82 | bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA); |
78 | int pwidth = xpa ? 11 : 8; | 83 | int pwidth = xpa ? 11 : 8; |
@@ -86,7 +91,9 @@ static void dump_tlb(int first, int last) | |||
86 | s_pagemask = read_c0_pagemask(); | 91 | s_pagemask = read_c0_pagemask(); |
87 | s_entryhi = read_c0_entryhi(); | 92 | s_entryhi = read_c0_entryhi(); |
88 | s_index = read_c0_index(); | 93 | s_index = read_c0_index(); |
89 | asid = s_entryhi & 0xff; | 94 | asid = s_entryhi & asidmask; |
95 | if (cpu_has_guestid) | ||
96 | s_guestctl1 = read_c0_guestctl1(); | ||
90 | 97 | ||
91 | for (i = first; i <= last; i++) { | 98 | for (i = first; i <= last; i++) { |
92 | write_c0_index(i); | 99 | write_c0_index(i); |
@@ -97,6 +104,8 @@ static void dump_tlb(int first, int last) | |||
97 | entryhi = read_c0_entryhi(); | 104 | entryhi = read_c0_entryhi(); |
98 | entrylo0 = read_c0_entrylo0(); | 105 | entrylo0 = read_c0_entrylo0(); |
99 | entrylo1 = read_c0_entrylo1(); | 106 | entrylo1 = read_c0_entrylo1(); |
107 | if (cpu_has_guestid) | ||
108 | guestctl1 = read_c0_guestctl1(); | ||
100 | 109 | ||
101 | /* EHINV bit marks entire entry as invalid */ | 110 | /* EHINV bit marks entire entry as invalid */ |
102 | if (cpu_has_tlbinv && entryhi & MIPS_ENTRYHI_EHINV) | 111 | if (cpu_has_tlbinv && entryhi & MIPS_ENTRYHI_EHINV) |
@@ -115,7 +124,7 @@ static void dump_tlb(int first, int last) | |||
115 | * due to duplicate TLB entry. | 124 | * due to duplicate TLB entry. |
116 | */ | 125 | */ |
117 | if (!((entrylo0 | entrylo1) & ENTRYLO_G) && | 126 | if (!((entrylo0 | entrylo1) & ENTRYLO_G) && |
118 | (entryhi & 0xff) != asid) | 127 | (entryhi & asidmask) != asid) |
119 | continue; | 128 | continue; |
120 | 129 | ||
121 | /* | 130 | /* |
@@ -126,15 +135,19 @@ static void dump_tlb(int first, int last) | |||
126 | c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; | 135 | c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; |
127 | c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; | 136 | c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; |
128 | 137 | ||
129 | printk("va=%0*lx asid=%02lx\n", | 138 | printk("va=%0*lx asid=%0*lx", |
130 | vwidth, (entryhi & ~0x1fffUL), | 139 | vwidth, (entryhi & ~0x1fffUL), |
131 | entryhi & 0xff); | 140 | asidwidth, entryhi & asidmask); |
141 | if (cpu_has_guestid) | ||
142 | printk(" gid=%02lx", | ||
143 | (guestctl1 & MIPS_GCTL1_RID) | ||
144 | >> MIPS_GCTL1_RID_SHIFT); | ||
132 | /* RI/XI are in awkward places, so mask them off separately */ | 145 | /* RI/XI are in awkward places, so mask them off separately */ |
133 | pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI); | 146 | pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI); |
134 | if (xpa) | 147 | if (xpa) |
135 | pa |= (unsigned long long)readx_c0_entrylo0() << 30; | 148 | pa |= (unsigned long long)readx_c0_entrylo0() << 30; |
136 | pa = (pa << 6) & PAGE_MASK; | 149 | pa = (pa << 6) & PAGE_MASK; |
137 | printk("\t["); | 150 | printk("\n\t["); |
138 | if (cpu_has_rixi) | 151 | if (cpu_has_rixi) |
139 | printk("ri=%d xi=%d ", | 152 | printk("ri=%d xi=%d ", |
140 | (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0, | 153 | (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0, |
@@ -164,6 +177,8 @@ static void dump_tlb(int first, int last) | |||
164 | write_c0_entryhi(s_entryhi); | 177 | write_c0_entryhi(s_entryhi); |
165 | write_c0_index(s_index); | 178 | write_c0_index(s_index); |
166 | write_c0_pagemask(s_pagemask); | 179 | write_c0_pagemask(s_pagemask); |
180 | if (cpu_has_guestid) | ||
181 | write_c0_guestctl1(s_guestctl1); | ||
167 | } | 182 | } |
168 | 183 | ||
169 | void dump_tlb_all(void) | 184 | void dump_tlb_all(void) |
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 8f0019a2e5c8..18a1ccd4d134 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S | |||
@@ -228,10 +228,12 @@ | |||
228 | .hidden __memset | 228 | .hidden __memset |
229 | .endif | 229 | .endif |
230 | 230 | ||
231 | #ifdef CONFIG_CPU_MIPSR6 | ||
231 | .Lbyte_fixup\@: | 232 | .Lbyte_fixup\@: |
232 | PTR_SUBU a2, $0, t0 | 233 | PTR_SUBU a2, $0, t0 |
233 | jr ra | 234 | jr ra |
234 | PTR_ADDIU a2, 1 | 235 | PTR_ADDIU a2, 1 |
236 | #endif /* CONFIG_CPU_MIPSR6 */ | ||
235 | 237 | ||
236 | .Lfirst_fixup\@: | 238 | .Lfirst_fixup\@: |
237 | jr ra | 239 | jr ra |
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index cfcbb5218b59..744f4a7bc49d 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c | |||
@@ -29,9 +29,10 @@ static void dump_tlb(int first, int last) | |||
29 | { | 29 | { |
30 | int i; | 30 | int i; |
31 | unsigned int asid; | 31 | unsigned int asid; |
32 | unsigned long entryhi, entrylo0; | 32 | unsigned long entryhi, entrylo0, asid_mask; |
33 | 33 | ||
34 | asid = read_c0_entryhi() & ASID_MASK; | 34 | asid_mask = cpu_asid_mask(¤t_cpu_data); |
35 | asid = read_c0_entryhi() & asid_mask; | ||
35 | 36 | ||
36 | for (i = first; i <= last; i++) { | 37 | for (i = first; i <= last; i++) { |
37 | write_c0_index(i<<8); | 38 | write_c0_index(i<<8); |
@@ -46,7 +47,7 @@ static void dump_tlb(int first, int last) | |||
46 | /* Unused entries have a virtual address of KSEG0. */ | 47 | /* Unused entries have a virtual address of KSEG0. */ |
47 | if ((entryhi & PAGE_MASK) != KSEG0 && | 48 | if ((entryhi & PAGE_MASK) != KSEG0 && |
48 | (entrylo0 & R3K_ENTRYLO_G || | 49 | (entrylo0 & R3K_ENTRYLO_G || |
49 | (entryhi & ASID_MASK) == asid)) { | 50 | (entryhi & asid_mask) == asid)) { |
50 | /* | 51 | /* |
51 | * Only print entries in use | 52 | * Only print entries in use |
52 | */ | 53 | */ |
@@ -55,7 +56,7 @@ static void dump_tlb(int first, int last) | |||
55 | printk("va=%08lx asid=%08lx" | 56 | printk("va=%08lx asid=%08lx" |
56 | " [pa=%06lx n=%d d=%d v=%d g=%d]", | 57 | " [pa=%06lx n=%d d=%d v=%d g=%d]", |
57 | entryhi & PAGE_MASK, | 58 | entryhi & PAGE_MASK, |
58 | entryhi & ASID_MASK, | 59 | entryhi & asid_mask, |
59 | entrylo0 & PAGE_MASK, | 60 | entrylo0 & PAGE_MASK, |
60 | (entrylo0 & R3K_ENTRYLO_N) ? 1 : 0, | 61 | (entrylo0 & R3K_ENTRYLO_N) ? 1 : 0, |
61 | (entrylo0 & R3K_ENTRYLO_D) ? 1 : 0, | 62 | (entrylo0 & R3K_ENTRYLO_D) ? 1 : 0, |
diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c index ddf1d4cbf31e..f2c714d8fb60 100644 --- a/arch/mips/loongson32/common/platform.c +++ b/arch/mips/loongson32/common/platform.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | 2 | * Copyright (c) 2011-2016 Zhang, Keguang <keguang.zhang@gmail.com> |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the | 5 | * under the terms of the GNU General Public License as published by the |
@@ -10,14 +10,17 @@ | |||
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/dma-mapping.h> | 11 | #include <linux/dma-mapping.h> |
12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
13 | #include <linux/mtd/partitions.h> | ||
14 | #include <linux/sizes.h> | ||
13 | #include <linux/phy.h> | 15 | #include <linux/phy.h> |
14 | #include <linux/serial_8250.h> | 16 | #include <linux/serial_8250.h> |
15 | #include <linux/stmmac.h> | 17 | #include <linux/stmmac.h> |
16 | #include <linux/usb/ehci_pdriver.h> | 18 | #include <linux/usb/ehci_pdriver.h> |
17 | #include <asm-generic/sizes.h> | ||
18 | 19 | ||
19 | #include <cpufreq.h> | ||
20 | #include <loongson1.h> | 20 | #include <loongson1.h> |
21 | #include <cpufreq.h> | ||
22 | #include <dma.h> | ||
23 | #include <nand.h> | ||
21 | 24 | ||
22 | /* 8250/16550 compatible UART */ | 25 | /* 8250/16550 compatible UART */ |
23 | #define LS1X_UART(_id) \ | 26 | #define LS1X_UART(_id) \ |
@@ -45,7 +48,7 @@ struct platform_device ls1x_uart_pdev = { | |||
45 | }, | 48 | }, |
46 | }; | 49 | }; |
47 | 50 | ||
48 | void __init ls1x_serial_setup(struct platform_device *pdev) | 51 | void __init ls1x_serial_set_uartclk(struct platform_device *pdev) |
49 | { | 52 | { |
50 | struct clk *clk; | 53 | struct clk *clk; |
51 | struct plat_serial8250_port *p; | 54 | struct plat_serial8250_port *p; |
@@ -77,6 +80,42 @@ struct platform_device ls1x_cpufreq_pdev = { | |||
77 | }, | 80 | }, |
78 | }; | 81 | }; |
79 | 82 | ||
83 | /* DMA */ | ||
84 | static struct resource ls1x_dma_resources[] = { | ||
85 | [0] = { | ||
86 | .start = LS1X_DMAC_BASE, | ||
87 | .end = LS1X_DMAC_BASE + SZ_4 - 1, | ||
88 | .flags = IORESOURCE_MEM, | ||
89 | }, | ||
90 | [1] = { | ||
91 | .start = LS1X_DMA0_IRQ, | ||
92 | .end = LS1X_DMA0_IRQ, | ||
93 | .flags = IORESOURCE_IRQ, | ||
94 | }, | ||
95 | [2] = { | ||
96 | .start = LS1X_DMA1_IRQ, | ||
97 | .end = LS1X_DMA1_IRQ, | ||
98 | .flags = IORESOURCE_IRQ, | ||
99 | }, | ||
100 | [3] = { | ||
101 | .start = LS1X_DMA2_IRQ, | ||
102 | .end = LS1X_DMA2_IRQ, | ||
103 | .flags = IORESOURCE_IRQ, | ||
104 | }, | ||
105 | }; | ||
106 | |||
107 | struct platform_device ls1x_dma_pdev = { | ||
108 | .name = "ls1x-dma", | ||
109 | .id = -1, | ||
110 | .num_resources = ARRAY_SIZE(ls1x_dma_resources), | ||
111 | .resource = ls1x_dma_resources, | ||
112 | }; | ||
113 | |||
114 | void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata) | ||
115 | { | ||
116 | ls1x_dma_pdev.dev.platform_data = pdata; | ||
117 | } | ||
118 | |||
80 | /* Synopsys Ethernet GMAC */ | 119 | /* Synopsys Ethernet GMAC */ |
81 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { | 120 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { |
82 | .phy_mask = 0, | 121 | .phy_mask = 0, |
@@ -198,6 +237,64 @@ struct platform_device ls1x_eth1_pdev = { | |||
198 | }, | 237 | }, |
199 | }; | 238 | }; |
200 | 239 | ||
240 | /* GPIO */ | ||
241 | static struct resource ls1x_gpio0_resources[] = { | ||
242 | [0] = { | ||
243 | .start = LS1X_GPIO0_BASE, | ||
244 | .end = LS1X_GPIO0_BASE + SZ_4 - 1, | ||
245 | .flags = IORESOURCE_MEM, | ||
246 | }, | ||
247 | }; | ||
248 | |||
249 | struct platform_device ls1x_gpio0_pdev = { | ||
250 | .name = "ls1x-gpio", | ||
251 | .id = 0, | ||
252 | .num_resources = ARRAY_SIZE(ls1x_gpio0_resources), | ||
253 | .resource = ls1x_gpio0_resources, | ||
254 | }; | ||
255 | |||
256 | static struct resource ls1x_gpio1_resources[] = { | ||
257 | [0] = { | ||
258 | .start = LS1X_GPIO1_BASE, | ||
259 | .end = LS1X_GPIO1_BASE + SZ_4 - 1, | ||
260 | .flags = IORESOURCE_MEM, | ||
261 | }, | ||
262 | }; | ||
263 | |||
264 | struct platform_device ls1x_gpio1_pdev = { | ||
265 | .name = "ls1x-gpio", | ||
266 | .id = 1, | ||
267 | .num_resources = ARRAY_SIZE(ls1x_gpio1_resources), | ||
268 | .resource = ls1x_gpio1_resources, | ||
269 | }; | ||
270 | |||
271 | /* NAND Flash */ | ||
272 | static struct resource ls1x_nand_resources[] = { | ||
273 | [0] = { | ||
274 | .start = LS1X_NAND_BASE, | ||
275 | .end = LS1X_NAND_BASE + SZ_32 - 1, | ||
276 | .flags = IORESOURCE_MEM, | ||
277 | }, | ||
278 | [1] = { | ||
279 | /* DMA channel 0 is dedicated to NAND */ | ||
280 | .start = LS1X_DMA_CHANNEL0, | ||
281 | .end = LS1X_DMA_CHANNEL0, | ||
282 | .flags = IORESOURCE_DMA, | ||
283 | }, | ||
284 | }; | ||
285 | |||
286 | struct platform_device ls1x_nand_pdev = { | ||
287 | .name = "ls1x-nand", | ||
288 | .id = -1, | ||
289 | .num_resources = ARRAY_SIZE(ls1x_nand_resources), | ||
290 | .resource = ls1x_nand_resources, | ||
291 | }; | ||
292 | |||
293 | void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata) | ||
294 | { | ||
295 | ls1x_nand_pdev.dev.platform_data = pdata; | ||
296 | } | ||
297 | |||
201 | /* USB EHCI */ | 298 | /* USB EHCI */ |
202 | static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); | 299 | static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); |
203 | 300 | ||
diff --git a/arch/mips/loongson32/common/reset.c b/arch/mips/loongson32/common/reset.c index c41e4ca56ab4..8a1d9cc5a134 100644 --- a/arch/mips/loongson32/common/reset.c +++ b/arch/mips/loongson32/common/reset.c | |||
@@ -9,12 +9,13 @@ | |||
9 | 9 | ||
10 | #include <linux/io.h> | 10 | #include <linux/io.h> |
11 | #include <linux/pm.h> | 11 | #include <linux/pm.h> |
12 | #include <linux/sizes.h> | ||
12 | #include <asm/idle.h> | 13 | #include <asm/idle.h> |
13 | #include <asm/reboot.h> | 14 | #include <asm/reboot.h> |
14 | 15 | ||
15 | #include <loongson1.h> | 16 | #include <loongson1.h> |
16 | 17 | ||
17 | static void __iomem *wdt_base; | 18 | static void __iomem *wdt_reg_base; |
18 | 19 | ||
19 | static void ls1x_halt(void) | 20 | static void ls1x_halt(void) |
20 | { | 21 | { |
@@ -26,9 +27,9 @@ static void ls1x_halt(void) | |||
26 | 27 | ||
27 | static void ls1x_restart(char *command) | 28 | static void ls1x_restart(char *command) |
28 | { | 29 | { |
29 | __raw_writel(0x1, wdt_base + WDT_EN); | 30 | __raw_writel(0x1, wdt_reg_base + WDT_EN); |
30 | __raw_writel(0x1, wdt_base + WDT_TIMER); | 31 | __raw_writel(0x1, wdt_reg_base + WDT_TIMER); |
31 | __raw_writel(0x1, wdt_base + WDT_SET); | 32 | __raw_writel(0x1, wdt_reg_base + WDT_SET); |
32 | 33 | ||
33 | ls1x_halt(); | 34 | ls1x_halt(); |
34 | } | 35 | } |
@@ -40,8 +41,8 @@ static void ls1x_power_off(void) | |||
40 | 41 | ||
41 | static int __init ls1x_reboot_setup(void) | 42 | static int __init ls1x_reboot_setup(void) |
42 | { | 43 | { |
43 | wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f); | 44 | wdt_reg_base = ioremap_nocache(LS1X_WDT_BASE, (SZ_4 + SZ_8)); |
44 | if (!wdt_base) | 45 | if (!wdt_reg_base) |
45 | panic("Failed to remap watchdog registers"); | 46 | panic("Failed to remap watchdog registers"); |
46 | 47 | ||
47 | _machine_restart = ls1x_restart; | 48 | _machine_restart = ls1x_restart; |
diff --git a/arch/mips/loongson32/common/time.c b/arch/mips/loongson32/common/time.c index 0996b025eeef..ff224f0020e5 100644 --- a/arch/mips/loongson32/common/time.c +++ b/arch/mips/loongson32/common/time.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/sizes.h> | ||
12 | #include <asm/time.h> | 13 | #include <asm/time.h> |
13 | 14 | ||
14 | #include <loongson1.h> | 15 | #include <loongson1.h> |
@@ -35,25 +36,25 @@ | |||
35 | 36 | ||
36 | DEFINE_RAW_SPINLOCK(ls1x_timer_lock); | 37 | DEFINE_RAW_SPINLOCK(ls1x_timer_lock); |
37 | 38 | ||
38 | static void __iomem *timer_base; | 39 | static void __iomem *timer_reg_base; |
39 | static uint32_t ls1x_jiffies_per_tick; | 40 | static uint32_t ls1x_jiffies_per_tick; |
40 | 41 | ||
41 | static inline void ls1x_pwmtimer_set_period(uint32_t period) | 42 | static inline void ls1x_pwmtimer_set_period(uint32_t period) |
42 | { | 43 | { |
43 | __raw_writel(period, timer_base + PWM_HRC); | 44 | __raw_writel(period, timer_reg_base + PWM_HRC); |
44 | __raw_writel(period, timer_base + PWM_LRC); | 45 | __raw_writel(period, timer_reg_base + PWM_LRC); |
45 | } | 46 | } |
46 | 47 | ||
47 | static inline void ls1x_pwmtimer_restart(void) | 48 | static inline void ls1x_pwmtimer_restart(void) |
48 | { | 49 | { |
49 | __raw_writel(0x0, timer_base + PWM_CNT); | 50 | __raw_writel(0x0, timer_reg_base + PWM_CNT); |
50 | __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); | 51 | __raw_writel(INT_EN | CNT_EN, timer_reg_base + PWM_CTRL); |
51 | } | 52 | } |
52 | 53 | ||
53 | void __init ls1x_pwmtimer_init(void) | 54 | void __init ls1x_pwmtimer_init(void) |
54 | { | 55 | { |
55 | timer_base = ioremap(LS1X_TIMER_BASE, 0xf); | 56 | timer_reg_base = ioremap_nocache(LS1X_TIMER_BASE, SZ_16); |
56 | if (!timer_base) | 57 | if (!timer_reg_base) |
57 | panic("Failed to remap timer registers"); | 58 | panic("Failed to remap timer registers"); |
58 | 59 | ||
59 | ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); | 60 | ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); |
@@ -86,7 +87,7 @@ static cycle_t ls1x_clocksource_read(struct clocksource *cs) | |||
86 | */ | 87 | */ |
87 | jifs = jiffies; | 88 | jifs = jiffies; |
88 | /* read the count */ | 89 | /* read the count */ |
89 | count = __raw_readl(timer_base + PWM_CNT); | 90 | count = __raw_readl(timer_reg_base + PWM_CNT); |
90 | 91 | ||
91 | /* | 92 | /* |
92 | * It's possible for count to appear to go the wrong way for this | 93 | * It's possible for count to appear to go the wrong way for this |
@@ -131,7 +132,7 @@ static int ls1x_clockevent_set_state_periodic(struct clock_event_device *cd) | |||
131 | raw_spin_lock(&ls1x_timer_lock); | 132 | raw_spin_lock(&ls1x_timer_lock); |
132 | ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); | 133 | ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); |
133 | ls1x_pwmtimer_restart(); | 134 | ls1x_pwmtimer_restart(); |
134 | __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); | 135 | __raw_writel(INT_EN | CNT_EN, timer_reg_base + PWM_CTRL); |
135 | raw_spin_unlock(&ls1x_timer_lock); | 136 | raw_spin_unlock(&ls1x_timer_lock); |
136 | 137 | ||
137 | return 0; | 138 | return 0; |
@@ -140,7 +141,7 @@ static int ls1x_clockevent_set_state_periodic(struct clock_event_device *cd) | |||
140 | static int ls1x_clockevent_tick_resume(struct clock_event_device *cd) | 141 | static int ls1x_clockevent_tick_resume(struct clock_event_device *cd) |
141 | { | 142 | { |
142 | raw_spin_lock(&ls1x_timer_lock); | 143 | raw_spin_lock(&ls1x_timer_lock); |
143 | __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); | 144 | __raw_writel(INT_EN | CNT_EN, timer_reg_base + PWM_CTRL); |
144 | raw_spin_unlock(&ls1x_timer_lock); | 145 | raw_spin_unlock(&ls1x_timer_lock); |
145 | 146 | ||
146 | return 0; | 147 | return 0; |
@@ -149,8 +150,8 @@ static int ls1x_clockevent_tick_resume(struct clock_event_device *cd) | |||
149 | static int ls1x_clockevent_set_state_shutdown(struct clock_event_device *cd) | 150 | static int ls1x_clockevent_set_state_shutdown(struct clock_event_device *cd) |
150 | { | 151 | { |
151 | raw_spin_lock(&ls1x_timer_lock); | 152 | raw_spin_lock(&ls1x_timer_lock); |
152 | __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN, | 153 | __raw_writel(__raw_readl(timer_reg_base + PWM_CTRL) & ~CNT_EN, |
153 | timer_base + PWM_CTRL); | 154 | timer_reg_base + PWM_CTRL); |
154 | raw_spin_unlock(&ls1x_timer_lock); | 155 | raw_spin_unlock(&ls1x_timer_lock); |
155 | 156 | ||
156 | return 0; | 157 | return 0; |
@@ -220,7 +221,7 @@ void __init plat_time_init(void) | |||
220 | 221 | ||
221 | #ifdef CONFIG_CEVT_CSRC_LS1X | 222 | #ifdef CONFIG_CEVT_CSRC_LS1X |
222 | /* setup LS1X PWM timer */ | 223 | /* setup LS1X PWM timer */ |
223 | clk = clk_get(NULL, "ls1x_pwmtimer"); | 224 | clk = clk_get(NULL, "ls1x-pwmtimer"); |
224 | if (IS_ERR(clk)) | 225 | if (IS_ERR(clk)) |
225 | panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); | 226 | panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); |
226 | 227 | ||
diff --git a/arch/mips/loongson32/ls1b/board.c b/arch/mips/loongson32/ls1b/board.c index 58daeea25739..38a1d404be1b 100644 --- a/arch/mips/loongson32/ls1b/board.c +++ b/arch/mips/loongson32/ls1b/board.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | 2 | * Copyright (c) 2011-2016 Zhang, Keguang <keguang.zhang@gmail.com> |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the | 5 | * under the terms of the GNU General Public License as published by the |
@@ -7,26 +7,83 @@ | |||
7 | * option) any later version. | 7 | * option) any later version. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/leds.h> | ||
11 | #include <linux/mtd/partitions.h> | ||
12 | #include <linux/sizes.h> | ||
13 | |||
14 | #include <loongson1.h> | ||
15 | #include <dma.h> | ||
16 | #include <nand.h> | ||
10 | #include <platform.h> | 17 | #include <platform.h> |
11 | 18 | ||
19 | struct plat_ls1x_dma ls1x_dma_pdata = { | ||
20 | .nr_channels = 3, | ||
21 | }; | ||
22 | |||
23 | static struct mtd_partition ls1x_nand_parts[] = { | ||
24 | { | ||
25 | .name = "kernel", | ||
26 | .offset = 0, | ||
27 | .size = SZ_16M, | ||
28 | }, | ||
29 | { | ||
30 | .name = "rootfs", | ||
31 | .offset = MTDPART_OFS_APPEND, | ||
32 | .size = MTDPART_SIZ_FULL, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | struct plat_ls1x_nand ls1x_nand_pdata = { | ||
37 | .parts = ls1x_nand_parts, | ||
38 | .nr_parts = ARRAY_SIZE(ls1x_nand_parts), | ||
39 | .hold_cycle = 0x2, | ||
40 | .wait_cycle = 0xc, | ||
41 | }; | ||
42 | |||
43 | static const struct gpio_led ls1x_gpio_leds[] __initconst = { | ||
44 | { | ||
45 | .name = "LED9", | ||
46 | .default_trigger = "heartbeat", | ||
47 | .gpio = 38, | ||
48 | .active_low = 1, | ||
49 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | ||
50 | }, { | ||
51 | .name = "LED6", | ||
52 | .default_trigger = "nand-disk", | ||
53 | .gpio = 39, | ||
54 | .active_low = 1, | ||
55 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | ||
56 | }, | ||
57 | }; | ||
58 | |||
59 | static const struct gpio_led_platform_data ls1x_led_pdata __initconst = { | ||
60 | .num_leds = ARRAY_SIZE(ls1x_gpio_leds), | ||
61 | .leds = ls1x_gpio_leds, | ||
62 | }; | ||
63 | |||
12 | static struct platform_device *ls1b_platform_devices[] __initdata = { | 64 | static struct platform_device *ls1b_platform_devices[] __initdata = { |
13 | &ls1x_uart_pdev, | 65 | &ls1x_uart_pdev, |
14 | &ls1x_cpufreq_pdev, | 66 | &ls1x_cpufreq_pdev, |
67 | &ls1x_dma_pdev, | ||
15 | &ls1x_eth0_pdev, | 68 | &ls1x_eth0_pdev, |
16 | &ls1x_eth1_pdev, | 69 | &ls1x_eth1_pdev, |
17 | &ls1x_ehci_pdev, | 70 | &ls1x_ehci_pdev, |
71 | &ls1x_gpio0_pdev, | ||
72 | &ls1x_gpio1_pdev, | ||
73 | &ls1x_nand_pdev, | ||
18 | &ls1x_rtc_pdev, | 74 | &ls1x_rtc_pdev, |
19 | }; | 75 | }; |
20 | 76 | ||
21 | static int __init ls1b_platform_init(void) | 77 | static int __init ls1b_platform_init(void) |
22 | { | 78 | { |
23 | int err; | 79 | ls1x_serial_set_uartclk(&ls1x_uart_pdev); |
80 | ls1x_dma_set_platdata(&ls1x_dma_pdata); | ||
81 | ls1x_nand_set_platdata(&ls1x_nand_pdata); | ||
24 | 82 | ||
25 | ls1x_serial_setup(&ls1x_uart_pdev); | 83 | gpio_led_register_device(-1, &ls1x_led_pdata); |
26 | 84 | ||
27 | err = platform_add_devices(ls1b_platform_devices, | 85 | return platform_add_devices(ls1b_platform_devices, |
28 | ARRAY_SIZE(ls1b_platform_devices)); | 86 | ARRAY_SIZE(ls1b_platform_devices)); |
29 | return err; | ||
30 | } | 87 | } |
31 | 88 | ||
32 | arch_initcall(ls1b_platform_init); | 89 | arch_initcall(ls1b_platform_init); |
diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform index 85d808924c94..0fce4608aa88 100644 --- a/arch/mips/loongson64/Platform +++ b/arch/mips/loongson64/Platform | |||
@@ -31,7 +31,7 @@ cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap | |||
31 | # can't easily be used safely within the kbuild framework. | 31 | # can't easily be used safely within the kbuild framework. |
32 | # | 32 | # |
33 | ifeq ($(call cc-ifversion, -ge, 0409, y), y) | 33 | ifeq ($(call cc-ifversion, -ge, 0409, y), y) |
34 | ifeq ($(call ld-ifversion, -ge, 22500000, y), y) | 34 | ifeq ($(call ld-ifversion, -ge, 225000000, y), y) |
35 | cflags-$(CONFIG_CPU_LOONGSON3) += \ | 35 | cflags-$(CONFIG_CPU_LOONGSON3) += \ |
36 | $(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) | 36 | $(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) |
37 | else | 37 | else |
diff --git a/arch/mips/loongson64/common/env.c b/arch/mips/loongson64/common/env.c index d6d07ad56180..57d590ac8004 100644 --- a/arch/mips/loongson64/common/env.c +++ b/arch/mips/loongson64/common/env.c | |||
@@ -105,6 +105,10 @@ void __init prom_init_env(void) | |||
105 | loongson_chiptemp[1] = 0x900010001fe0019c; | 105 | loongson_chiptemp[1] = 0x900010001fe0019c; |
106 | loongson_chiptemp[2] = 0x900020001fe0019c; | 106 | loongson_chiptemp[2] = 0x900020001fe0019c; |
107 | loongson_chiptemp[3] = 0x900030001fe0019c; | 107 | loongson_chiptemp[3] = 0x900030001fe0019c; |
108 | loongson_freqctrl[0] = 0x900000001fe001d0; | ||
109 | loongson_freqctrl[1] = 0x900010001fe001d0; | ||
110 | loongson_freqctrl[2] = 0x900020001fe001d0; | ||
111 | loongson_freqctrl[3] = 0x900030001fe001d0; | ||
108 | loongson_sysconf.ht_control_base = 0x90000EFDFB000000; | 112 | loongson_sysconf.ht_control_base = 0x90000EFDFB000000; |
109 | loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; | 113 | loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; |
110 | } else if (ecpu->cputype == Loongson_3B) { | 114 | } else if (ecpu->cputype == Loongson_3B) { |
@@ -187,7 +191,8 @@ void __init prom_init_env(void) | |||
187 | case PRID_REV_LOONGSON2F: | 191 | case PRID_REV_LOONGSON2F: |
188 | cpu_clock_freq = 797000000; | 192 | cpu_clock_freq = 797000000; |
189 | break; | 193 | break; |
190 | case PRID_REV_LOONGSON3A: | 194 | case PRID_REV_LOONGSON3A_R1: |
195 | case PRID_REV_LOONGSON3A_R2: | ||
191 | cpu_clock_freq = 900000000; | 196 | cpu_clock_freq = 900000000; |
192 | break; | 197 | break; |
193 | case PRID_REV_LOONGSON3B_R1: | 198 | case PRID_REV_LOONGSON3B_R1: |
diff --git a/arch/mips/loongson64/loongson-3/Makefile b/arch/mips/loongson64/loongson-3/Makefile index 622fead5ebc9..44bc1482158b 100644 --- a/arch/mips/loongson64/loongson-3/Makefile +++ b/arch/mips/loongson64/loongson-3/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Makefile for Loongson-3 family machines | 2 | # Makefile for Loongson-3 family machines |
3 | # | 3 | # |
4 | obj-y += irq.o cop2-ex.o platform.o | 4 | obj-y += irq.o cop2-ex.o platform.o acpi_init.o |
5 | 5 | ||
6 | obj-$(CONFIG_SMP) += smp.o | 6 | obj-$(CONFIG_SMP) += smp.o |
7 | 7 | ||
diff --git a/drivers/platform/mips/acpi_init.c b/arch/mips/loongson64/loongson-3/acpi_init.c index dbdad79ead8f..dbdad79ead8f 100644 --- a/drivers/platform/mips/acpi_init.c +++ b/arch/mips/loongson64/loongson-3/acpi_init.c | |||
diff --git a/arch/mips/loongson64/loongson-3/irq.c b/arch/mips/loongson64/loongson-3/irq.c index 0f75b6b3d218..8e7649088353 100644 --- a/arch/mips/loongson64/loongson-3/irq.c +++ b/arch/mips/loongson64/loongson-3/irq.c | |||
@@ -24,19 +24,21 @@ static void ht_irqdispatch(void) | |||
24 | } | 24 | } |
25 | } | 25 | } |
26 | 26 | ||
27 | #define UNUSED_IPS (CAUSEF_IP5 | CAUSEF_IP4 | CAUSEF_IP1 | CAUSEF_IP0) | ||
28 | |||
27 | void mach_irq_dispatch(unsigned int pending) | 29 | void mach_irq_dispatch(unsigned int pending) |
28 | { | 30 | { |
29 | if (pending & CAUSEF_IP7) | 31 | if (pending & CAUSEF_IP7) |
30 | do_IRQ(LOONGSON_TIMER_IRQ); | 32 | do_IRQ(LOONGSON_TIMER_IRQ); |
31 | #if defined(CONFIG_SMP) | 33 | #if defined(CONFIG_SMP) |
32 | else if (pending & CAUSEF_IP6) | 34 | if (pending & CAUSEF_IP6) |
33 | loongson3_ipi_interrupt(NULL); | 35 | loongson3_ipi_interrupt(NULL); |
34 | #endif | 36 | #endif |
35 | else if (pending & CAUSEF_IP3) | 37 | if (pending & CAUSEF_IP3) |
36 | ht_irqdispatch(); | 38 | ht_irqdispatch(); |
37 | else if (pending & CAUSEF_IP2) | 39 | if (pending & CAUSEF_IP2) |
38 | do_IRQ(LOONGSON_UART_IRQ); | 40 | do_IRQ(LOONGSON_UART_IRQ); |
39 | else { | 41 | if (pending & UNUSED_IPS) { |
40 | pr_err("%s : spurious interrupt\n", __func__); | 42 | pr_err("%s : spurious interrupt\n", __func__); |
41 | spurious_interrupt(); | 43 | spurious_interrupt(); |
42 | } | 44 | } |
diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c index 6f9e010cec4d..282c5a8c2fcd 100644 --- a/arch/mips/loongson64/loongson-3/numa.c +++ b/arch/mips/loongson64/loongson-3/numa.c | |||
@@ -213,10 +213,10 @@ static void __init node_mem_init(unsigned int node) | |||
213 | BOOTMEM_DEFAULT); | 213 | BOOTMEM_DEFAULT); |
214 | 214 | ||
215 | if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) { | 215 | if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) { |
216 | /* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */ | 216 | /* Reserve 0xfe000000~0xffffffff for RS780E integrated GPU */ |
217 | reserve_bootmem_node(NODE_DATA(node), | 217 | reserve_bootmem_node(NODE_DATA(node), |
218 | (node_addrspace_offset | 0xff800000), | 218 | (node_addrspace_offset | 0xfe000000), |
219 | 8 << 20, BOOTMEM_DEFAULT); | 219 | 32 << 20, BOOTMEM_DEFAULT); |
220 | } | 220 | } |
221 | 221 | ||
222 | sparse_memory_present_with_active_regions(node); | 222 | sparse_memory_present_with_active_regions(node); |
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index 509832a9836c..e59759af63d9 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c | |||
@@ -421,7 +421,6 @@ static int loongson3_cpu_disable(void) | |||
421 | local_irq_save(flags); | 421 | local_irq_save(flags); |
422 | fixup_irqs(); | 422 | fixup_irqs(); |
423 | local_irq_restore(flags); | 423 | local_irq_restore(flags); |
424 | flush_cache_all(); | ||
425 | local_flush_tlb_all(); | 424 | local_flush_tlb_all(); |
426 | 425 | ||
427 | return 0; | 426 | return 0; |
@@ -440,7 +439,7 @@ static void loongson3_cpu_die(unsigned int cpu) | |||
440 | * flush all L1 entries at first. Then, another core (usually Core 0) can | 439 | * flush all L1 entries at first. Then, another core (usually Core 0) can |
441 | * safely disable the clock of the target core. loongson3_play_dead() is | 440 | * safely disable the clock of the target core. loongson3_play_dead() is |
442 | * called via CKSEG1 (uncached and unmmaped) */ | 441 | * called via CKSEG1 (uncached and unmmaped) */ |
443 | static void loongson3a_play_dead(int *state_addr) | 442 | static void loongson3a_r1_play_dead(int *state_addr) |
444 | { | 443 | { |
445 | register int val; | 444 | register int val; |
446 | register long cpuid, core, node, count; | 445 | register long cpuid, core, node, count; |
@@ -502,6 +501,89 @@ static void loongson3a_play_dead(int *state_addr) | |||
502 | : "a1"); | 501 | : "a1"); |
503 | } | 502 | } |
504 | 503 | ||
504 | static void loongson3a_r2_play_dead(int *state_addr) | ||
505 | { | ||
506 | register int val; | ||
507 | register long cpuid, core, node, count; | ||
508 | register void *addr, *base, *initfunc; | ||
509 | |||
510 | __asm__ __volatile__( | ||
511 | " .set push \n" | ||
512 | " .set noreorder \n" | ||
513 | " li %[addr], 0x80000000 \n" /* KSEG0 */ | ||
514 | "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */ | ||
515 | " cache 0, 1(%[addr]) \n" | ||
516 | " cache 0, 2(%[addr]) \n" | ||
517 | " cache 0, 3(%[addr]) \n" | ||
518 | " cache 1, 0(%[addr]) \n" /* flush L1 DCache */ | ||
519 | " cache 1, 1(%[addr]) \n" | ||
520 | " cache 1, 2(%[addr]) \n" | ||
521 | " cache 1, 3(%[addr]) \n" | ||
522 | " addiu %[sets], %[sets], -1 \n" | ||
523 | " bnez %[sets], 1b \n" | ||
524 | " addiu %[addr], %[addr], 0x40 \n" | ||
525 | " li %[addr], 0x80000000 \n" /* KSEG0 */ | ||
526 | "2: cache 2, 0(%[addr]) \n" /* flush L1 VCache */ | ||
527 | " cache 2, 1(%[addr]) \n" | ||
528 | " cache 2, 2(%[addr]) \n" | ||
529 | " cache 2, 3(%[addr]) \n" | ||
530 | " cache 2, 4(%[addr]) \n" | ||
531 | " cache 2, 5(%[addr]) \n" | ||
532 | " cache 2, 6(%[addr]) \n" | ||
533 | " cache 2, 7(%[addr]) \n" | ||
534 | " cache 2, 8(%[addr]) \n" | ||
535 | " cache 2, 9(%[addr]) \n" | ||
536 | " cache 2, 10(%[addr]) \n" | ||
537 | " cache 2, 11(%[addr]) \n" | ||
538 | " cache 2, 12(%[addr]) \n" | ||
539 | " cache 2, 13(%[addr]) \n" | ||
540 | " cache 2, 14(%[addr]) \n" | ||
541 | " cache 2, 15(%[addr]) \n" | ||
542 | " addiu %[vsets], %[vsets], -1 \n" | ||
543 | " bnez %[vsets], 2b \n" | ||
544 | " addiu %[addr], %[addr], 0x40 \n" | ||
545 | " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */ | ||
546 | " sw %[val], (%[state_addr]) \n" | ||
547 | " sync \n" | ||
548 | " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */ | ||
549 | " .set pop \n" | ||
550 | : [addr] "=&r" (addr), [val] "=&r" (val) | ||
551 | : [state_addr] "r" (state_addr), | ||
552 | [sets] "r" (cpu_data[smp_processor_id()].dcache.sets), | ||
553 | [vsets] "r" (cpu_data[smp_processor_id()].vcache.sets)); | ||
554 | |||
555 | __asm__ __volatile__( | ||
556 | " .set push \n" | ||
557 | " .set noreorder \n" | ||
558 | " .set mips64 \n" | ||
559 | " mfc0 %[cpuid], $15, 1 \n" | ||
560 | " andi %[cpuid], 0x3ff \n" | ||
561 | " dli %[base], 0x900000003ff01000 \n" | ||
562 | " andi %[core], %[cpuid], 0x3 \n" | ||
563 | " sll %[core], 8 \n" /* get core id */ | ||
564 | " or %[base], %[base], %[core] \n" | ||
565 | " andi %[node], %[cpuid], 0xc \n" | ||
566 | " dsll %[node], 42 \n" /* get node id */ | ||
567 | " or %[base], %[base], %[node] \n" | ||
568 | "1: li %[count], 0x100 \n" /* wait for init loop */ | ||
569 | "2: bnez %[count], 2b \n" /* limit mailbox access */ | ||
570 | " addiu %[count], -1 \n" | ||
571 | " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */ | ||
572 | " beqz %[initfunc], 1b \n" | ||
573 | " nop \n" | ||
574 | " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */ | ||
575 | " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */ | ||
576 | " ld $a1, 0x38(%[base]) \n" | ||
577 | " jr %[initfunc] \n" /* jump to initial PC */ | ||
578 | " nop \n" | ||
579 | " .set pop \n" | ||
580 | : [core] "=&r" (core), [node] "=&r" (node), | ||
581 | [base] "=&r" (base), [cpuid] "=&r" (cpuid), | ||
582 | [count] "=&r" (count), [initfunc] "=&r" (initfunc) | ||
583 | : /* No Input */ | ||
584 | : "a1"); | ||
585 | } | ||
586 | |||
505 | static void loongson3b_play_dead(int *state_addr) | 587 | static void loongson3b_play_dead(int *state_addr) |
506 | { | 588 | { |
507 | register int val; | 589 | register int val; |
@@ -573,13 +655,18 @@ void play_dead(void) | |||
573 | void (*play_dead_at_ckseg1)(int *); | 655 | void (*play_dead_at_ckseg1)(int *); |
574 | 656 | ||
575 | idle_task_exit(); | 657 | idle_task_exit(); |
576 | switch (loongson_sysconf.cputype) { | 658 | switch (read_c0_prid() & PRID_REV_MASK) { |
577 | case Loongson_3A: | 659 | case PRID_REV_LOONGSON3A_R1: |
578 | default: | 660 | default: |
579 | play_dead_at_ckseg1 = | 661 | play_dead_at_ckseg1 = |
580 | (void *)CKSEG1ADDR((unsigned long)loongson3a_play_dead); | 662 | (void *)CKSEG1ADDR((unsigned long)loongson3a_r1_play_dead); |
663 | break; | ||
664 | case PRID_REV_LOONGSON3A_R2: | ||
665 | play_dead_at_ckseg1 = | ||
666 | (void *)CKSEG1ADDR((unsigned long)loongson3a_r2_play_dead); | ||
581 | break; | 667 | break; |
582 | case Loongson_3B: | 668 | case PRID_REV_LOONGSON3B_R1: |
669 | case PRID_REV_LOONGSON3B_R2: | ||
583 | play_dead_at_ckseg1 = | 670 | play_dead_at_ckseg1 = |
584 | (void *)CKSEG1ADDR((unsigned long)loongson3b_play_dead); | 671 | (void *)CKSEG1ADDR((unsigned long)loongson3b_play_dead); |
585 | break; | 672 | break; |
@@ -594,9 +681,9 @@ void loongson3_disable_clock(int cpu) | |||
594 | uint64_t core_id = cpu_data[cpu].core; | 681 | uint64_t core_id = cpu_data[cpu].core; |
595 | uint64_t package_id = cpu_data[cpu].package; | 682 | uint64_t package_id = cpu_data[cpu].package; |
596 | 683 | ||
597 | if (loongson_sysconf.cputype == Loongson_3A) { | 684 | if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { |
598 | LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); | 685 | LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); |
599 | } else if (loongson_sysconf.cputype == Loongson_3B) { | 686 | } else { |
600 | if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) | 687 | if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) |
601 | LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); | 688 | LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); |
602 | } | 689 | } |
@@ -607,9 +694,9 @@ void loongson3_enable_clock(int cpu) | |||
607 | uint64_t core_id = cpu_data[cpu].core; | 694 | uint64_t core_id = cpu_data[cpu].core; |
608 | uint64_t package_id = cpu_data[cpu].package; | 695 | uint64_t package_id = cpu_data[cpu].package; |
609 | 696 | ||
610 | if (loongson_sysconf.cputype == Loongson_3A) { | 697 | if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { |
611 | LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); | 698 | LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); |
612 | } else if (loongson_sysconf.cputype == Loongson_3B) { | 699 | } else { |
613 | if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) | 700 | if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) |
614 | LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); | 701 | LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); |
615 | } | 702 | } |
diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile index a19641d3ac23..e9bbc2a6526f 100644 --- a/arch/mips/math-emu/Makefile +++ b/arch/mips/math-emu/Makefile | |||
@@ -4,9 +4,9 @@ | |||
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_msubf.o dp_2008class.o dp_fmin.o dp_fmax.o \ | 7 | dp_tint.o dp_fint.o dp_maddf.o dp_2008class.o dp_fmin.o 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 \ | 8 | 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_msubf.o sp_2008class.o sp_fmin.o sp_fmax.o \ | 9 | sp_tint.o sp_fint.o sp_maddf.o sp_2008class.o sp_fmin.o sp_fmax.o \ |
10 | dsemul.o | 10 | dsemul.o |
11 | 11 | ||
12 | lib-y += ieee754d.o \ | 12 | lib-y += ieee754d.o \ |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index cdfd44ffa51c..d96e912b9d44 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -445,9 +445,11 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, | |||
445 | case spec_op: | 445 | case spec_op: |
446 | switch (insn.r_format.func) { | 446 | switch (insn.r_format.func) { |
447 | case jalr_op: | 447 | case jalr_op: |
448 | regs->regs[insn.r_format.rd] = | 448 | if (insn.r_format.rd != 0) { |
449 | regs->cp0_epc + dec_insn.pc_inc + | 449 | regs->regs[insn.r_format.rd] = |
450 | dec_insn.next_pc_inc; | 450 | regs->cp0_epc + dec_insn.pc_inc + |
451 | dec_insn.next_pc_inc; | ||
452 | } | ||
451 | /* Fall through */ | 453 | /* Fall through */ |
452 | case jr_op: | 454 | case jr_op: |
453 | /* For R6, JR already emulated in jalr_op */ | 455 | /* For R6, JR already emulated in jalr_op */ |
@@ -973,9 +975,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
973 | struct mm_decoded_insn dec_insn, void *__user *fault_addr) | 975 | struct mm_decoded_insn dec_insn, void *__user *fault_addr) |
974 | { | 976 | { |
975 | unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc; | 977 | unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc; |
976 | unsigned int cond, cbit; | 978 | unsigned int cond, cbit, bit0; |
977 | mips_instruction ir; | 979 | mips_instruction ir; |
978 | int likely, pc_inc; | 980 | int likely, pc_inc; |
981 | union fpureg *fpr; | ||
979 | u32 __user *wva; | 982 | u32 __user *wva; |
980 | u64 __user *dva; | 983 | u64 __user *dva; |
981 | u32 wval; | 984 | u32 wval; |
@@ -1187,14 +1190,14 @@ emul: | |||
1187 | return SIGILL; | 1190 | return SIGILL; |
1188 | 1191 | ||
1189 | cond = likely = 0; | 1192 | cond = likely = 0; |
1193 | fpr = ¤t->thread.fpu.fpr[MIPSInst_RT(ir)]; | ||
1194 | bit0 = get_fpr32(fpr, 0) & 0x1; | ||
1190 | switch (MIPSInst_RS(ir)) { | 1195 | switch (MIPSInst_RS(ir)) { |
1191 | case bc1eqz_op: | 1196 | case bc1eqz_op: |
1192 | if (get_fpr32(¤t->thread.fpu.fpr[MIPSInst_RT(ir)], 0) & 0x1) | 1197 | cond = bit0 == 0; |
1193 | cond = 1; | ||
1194 | break; | 1198 | break; |
1195 | case bc1nez_op: | 1199 | case bc1nez_op: |
1196 | if (!(get_fpr32(¤t->thread.fpu.fpr[MIPSInst_RT(ir)], 0) & 0x1)) | 1200 | cond = bit0 != 0; |
1197 | cond = 1; | ||
1198 | break; | 1201 | break; |
1199 | } | 1202 | } |
1200 | goto branch_common; | 1203 | goto branch_common; |
@@ -1674,7 +1677,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1674 | union ieee754sp(*b) (union ieee754sp, union ieee754sp); | 1677 | union ieee754sp(*b) (union ieee754sp, union ieee754sp); |
1675 | union ieee754sp(*u) (union ieee754sp); | 1678 | union ieee754sp(*u) (union ieee754sp); |
1676 | } handler; | 1679 | } handler; |
1677 | union ieee754sp fs, ft; | 1680 | union ieee754sp fd, fs, ft; |
1678 | 1681 | ||
1679 | switch (MIPSInst_FUNC(ir)) { | 1682 | switch (MIPSInst_FUNC(ir)) { |
1680 | /* binary ops */ | 1683 | /* binary ops */ |
@@ -1945,6 +1948,17 @@ copcsr: | |||
1945 | rfmt = w_fmt; | 1948 | rfmt = w_fmt; |
1946 | goto copcsr; | 1949 | goto copcsr; |
1947 | 1950 | ||
1951 | case fsel_op: | ||
1952 | if (!cpu_has_mips_r6) | ||
1953 | return SIGILL; | ||
1954 | |||
1955 | SPFROMREG(fd, MIPSInst_FD(ir)); | ||
1956 | if (fd.bits & 0x1) | ||
1957 | SPFROMREG(rv.s, MIPSInst_FT(ir)); | ||
1958 | else | ||
1959 | SPFROMREG(rv.s, MIPSInst_FS(ir)); | ||
1960 | break; | ||
1961 | |||
1948 | case fcvtl_op: | 1962 | case fcvtl_op: |
1949 | if (!cpu_has_mips_3_4_5_64_r2_r6) | 1963 | if (!cpu_has_mips_3_4_5_64_r2_r6) |
1950 | return SIGILL; | 1964 | return SIGILL; |
@@ -1993,7 +2007,7 @@ copcsr: | |||
1993 | } | 2007 | } |
1994 | 2008 | ||
1995 | case d_fmt: { | 2009 | case d_fmt: { |
1996 | union ieee754dp fs, ft; | 2010 | union ieee754dp fd, fs, ft; |
1997 | union { | 2011 | union { |
1998 | union ieee754dp(*b) (union ieee754dp, union ieee754dp); | 2012 | union ieee754dp(*b) (union ieee754dp, union ieee754dp); |
1999 | union ieee754dp(*u) (union ieee754dp); | 2013 | union ieee754dp(*u) (union ieee754dp); |
@@ -2243,6 +2257,17 @@ dcopuop: | |||
2243 | rfmt = w_fmt; | 2257 | rfmt = w_fmt; |
2244 | goto copcsr; | 2258 | goto copcsr; |
2245 | 2259 | ||
2260 | case fsel_op: | ||
2261 | if (!cpu_has_mips_r6) | ||
2262 | return SIGILL; | ||
2263 | |||
2264 | DPFROMREG(fd, MIPSInst_FD(ir)); | ||
2265 | if (fd.bits & 0x1) | ||
2266 | DPFROMREG(rv.d, MIPSInst_FT(ir)); | ||
2267 | else | ||
2268 | DPFROMREG(rv.d, MIPSInst_FS(ir)); | ||
2269 | break; | ||
2270 | |||
2246 | case fcvtl_op: | 2271 | case fcvtl_op: |
2247 | if (!cpu_has_mips_3_4_5_64_r2_r6) | 2272 | if (!cpu_has_mips_3_4_5_64_r2_r6) |
2248 | return SIGILL; | 2273 | return SIGILL; |
diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c index 119eda9fa1ea..4a2d03c72959 100644 --- a/arch/mips/math-emu/dp_maddf.c +++ b/arch/mips/math-emu/dp_maddf.c | |||
@@ -14,8 +14,12 @@ | |||
14 | 14 | ||
15 | #include "ieee754dp.h" | 15 | #include "ieee754dp.h" |
16 | 16 | ||
17 | union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | 17 | enum maddf_flags { |
18 | union ieee754dp y) | 18 | maddf_negate_product = 1 << 0, |
19 | }; | ||
20 | |||
21 | static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, | ||
22 | union ieee754dp y, enum maddf_flags flags) | ||
19 | { | 23 | { |
20 | int re; | 24 | int re; |
21 | int rs; | 25 | int rs; |
@@ -32,16 +36,15 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | |||
32 | 36 | ||
33 | COMPXDP; | 37 | COMPXDP; |
34 | COMPYDP; | 38 | COMPYDP; |
35 | 39 | COMPZDP; | |
36 | u64 zm; int ze; int zs __maybe_unused; int zc; | ||
37 | 40 | ||
38 | EXPLODEXDP; | 41 | EXPLODEXDP; |
39 | EXPLODEYDP; | 42 | EXPLODEYDP; |
40 | EXPLODEDP(z, zc, zs, ze, zm) | 43 | EXPLODEZDP; |
41 | 44 | ||
42 | FLUSHXDP; | 45 | FLUSHXDP; |
43 | FLUSHYDP; | 46 | FLUSHYDP; |
44 | FLUSHDP(z, zc, zs, ze, zm); | 47 | FLUSHZDP; |
45 | 48 | ||
46 | ieee754_clearcx(); | 49 | ieee754_clearcx(); |
47 | 50 | ||
@@ -50,7 +53,7 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | |||
50 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 53 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
51 | return ieee754dp_nanxcpt(z); | 54 | return ieee754dp_nanxcpt(z); |
52 | case IEEE754_CLASS_DNORM: | 55 | case IEEE754_CLASS_DNORM: |
53 | DPDNORMx(zm, ze); | 56 | DPDNORMZ; |
54 | /* QNAN is handled separately below */ | 57 | /* QNAN is handled separately below */ |
55 | } | 58 | } |
56 | 59 | ||
@@ -154,13 +157,15 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | |||
154 | 157 | ||
155 | re = xe + ye; | 158 | re = xe + ye; |
156 | rs = xs ^ ys; | 159 | rs = xs ^ ys; |
160 | if (flags & maddf_negate_product) | ||
161 | rs ^= 1; | ||
157 | 162 | ||
158 | /* shunt to top of word */ | 163 | /* shunt to top of word */ |
159 | xm <<= 64 - (DP_FBITS + 1); | 164 | xm <<= 64 - (DP_FBITS + 1); |
160 | ym <<= 64 - (DP_FBITS + 1); | 165 | ym <<= 64 - (DP_FBITS + 1); |
161 | 166 | ||
162 | /* | 167 | /* |
163 | * Multiply 32 bits xm, ym to give high 32 bits rm with stickness. | 168 | * Multiply 64 bits xm, ym to give high 64 bits rm with stickness. |
164 | */ | 169 | */ |
165 | 170 | ||
166 | /* 32 * 32 => 64 */ | 171 | /* 32 * 32 => 64 */ |
@@ -198,7 +203,7 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | |||
198 | if ((s64) rm < 0) { | 203 | if ((s64) rm < 0) { |
199 | rm = (rm >> (64 - (DP_FBITS + 1 + 3))) | | 204 | rm = (rm >> (64 - (DP_FBITS + 1 + 3))) | |
200 | ((rm << (DP_FBITS + 1 + 3)) != 0); | 205 | ((rm << (DP_FBITS + 1 + 3)) != 0); |
201 | re++; | 206 | re++; |
202 | } else { | 207 | } else { |
203 | rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) | | 208 | rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) | |
204 | ((rm << (DP_FBITS + 1 + 3 + 1)) != 0); | 209 | ((rm << (DP_FBITS + 1 + 3 + 1)) != 0); |
@@ -263,3 +268,15 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | |||
263 | 268 | ||
264 | return ieee754dp_format(zs, ze, zm); | 269 | return ieee754dp_format(zs, ze, zm); |
265 | } | 270 | } |
271 | |||
272 | union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | ||
273 | union ieee754dp y) | ||
274 | { | ||
275 | return _dp_maddf(z, x, y, 0); | ||
276 | } | ||
277 | |||
278 | union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, | ||
279 | union ieee754dp y) | ||
280 | { | ||
281 | return _dp_maddf(z, x, y, maddf_negate_product); | ||
282 | } | ||
diff --git a/arch/mips/math-emu/dp_msubf.c b/arch/mips/math-emu/dp_msubf.c deleted file mode 100644 index 12241262f856..000000000000 --- a/arch/mips/math-emu/dp_msubf.c +++ /dev/null | |||
@@ -1,269 +0,0 @@ | |||
1 | /* | ||
2 | * IEEE754 floating point arithmetic | ||
3 | * double precision: MSUB.f (Fused Multiply Subtract) | ||
4 | * MSUBF.fmt: FPR[fd] = FPR[fd] - (FPR[fs] x FPR[ft]) | ||
5 | * | ||
6 | * MIPS floating point support | ||
7 | * Copyright (C) 2015 Imagination Technologies, Ltd. | ||
8 | * Author: Markos Chandras <markos.chandras@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 as published by the | ||
12 | * Free Software Foundation; version 2 of the License. | ||
13 | */ | ||
14 | |||
15 | #include "ieee754dp.h" | ||
16 | |||
17 | union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, | ||
18 | union ieee754dp y) | ||
19 | { | ||
20 | int re; | ||
21 | int rs; | ||
22 | u64 rm; | ||
23 | unsigned lxm; | ||
24 | unsigned hxm; | ||
25 | unsigned lym; | ||
26 | unsigned hym; | ||
27 | u64 lrm; | ||
28 | u64 hrm; | ||
29 | u64 t; | ||
30 | u64 at; | ||
31 | int s; | ||
32 | |||
33 | COMPXDP; | ||
34 | COMPYDP; | ||
35 | |||
36 | u64 zm; int ze; int zs __maybe_unused; int zc; | ||
37 | |||
38 | EXPLODEXDP; | ||
39 | EXPLODEYDP; | ||
40 | EXPLODEDP(z, zc, zs, ze, zm) | ||
41 | |||
42 | FLUSHXDP; | ||
43 | FLUSHYDP; | ||
44 | FLUSHDP(z, zc, zs, ze, zm); | ||
45 | |||
46 | ieee754_clearcx(); | ||
47 | |||
48 | switch (zc) { | ||
49 | case IEEE754_CLASS_SNAN: | ||
50 | ieee754_setcx(IEEE754_INVALID_OPERATION); | ||
51 | return ieee754dp_nanxcpt(z); | ||
52 | case IEEE754_CLASS_DNORM: | ||
53 | DPDNORMx(zm, ze); | ||
54 | /* QNAN is handled separately below */ | ||
55 | } | ||
56 | |||
57 | switch (CLPAIR(xc, yc)) { | ||
58 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): | ||
59 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): | ||
60 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): | ||
61 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): | ||
62 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): | ||
63 | return ieee754dp_nanxcpt(y); | ||
64 | |||
65 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): | ||
66 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): | ||
67 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): | ||
68 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): | ||
69 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): | ||
70 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): | ||
71 | return ieee754dp_nanxcpt(x); | ||
72 | |||
73 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): | ||
74 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): | ||
75 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): | ||
76 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): | ||
77 | return y; | ||
78 | |||
79 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): | ||
80 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): | ||
81 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): | ||
82 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): | ||
83 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): | ||
84 | return x; | ||
85 | |||
86 | |||
87 | /* | ||
88 | * Infinity handling | ||
89 | */ | ||
90 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): | ||
91 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): | ||
92 | if (zc == IEEE754_CLASS_QNAN) | ||
93 | return z; | ||
94 | ieee754_setcx(IEEE754_INVALID_OPERATION); | ||
95 | return ieee754dp_indef(); | ||
96 | |||
97 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): | ||
98 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): | ||
99 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): | ||
100 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): | ||
101 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): | ||
102 | if (zc == IEEE754_CLASS_QNAN) | ||
103 | return z; | ||
104 | return ieee754dp_inf(xs ^ ys); | ||
105 | |||
106 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): | ||
107 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): | ||
108 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): | ||
109 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): | ||
110 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): | ||
111 | if (zc == IEEE754_CLASS_INF) | ||
112 | return ieee754dp_inf(zs); | ||
113 | /* Multiplication is 0 so just return z */ | ||
114 | return z; | ||
115 | |||
116 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): | ||
117 | DPDNORMX; | ||
118 | |||
119 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): | ||
120 | if (zc == IEEE754_CLASS_QNAN) | ||
121 | return z; | ||
122 | else if (zc == IEEE754_CLASS_INF) | ||
123 | return ieee754dp_inf(zs); | ||
124 | DPDNORMY; | ||
125 | break; | ||
126 | |||
127 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): | ||
128 | if (zc == IEEE754_CLASS_QNAN) | ||
129 | return z; | ||
130 | else if (zc == IEEE754_CLASS_INF) | ||
131 | return ieee754dp_inf(zs); | ||
132 | DPDNORMX; | ||
133 | break; | ||
134 | |||
135 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): | ||
136 | if (zc == IEEE754_CLASS_QNAN) | ||
137 | return z; | ||
138 | else if (zc == IEEE754_CLASS_INF) | ||
139 | return ieee754dp_inf(zs); | ||
140 | /* fall through to real computations */ | ||
141 | } | ||
142 | |||
143 | /* Finally get to do some computation */ | ||
144 | |||
145 | /* | ||
146 | * Do the multiplication bit first | ||
147 | * | ||
148 | * rm = xm * ym, re = xe + ye basically | ||
149 | * | ||
150 | * At this point xm and ym should have been normalized. | ||
151 | */ | ||
152 | assert(xm & DP_HIDDEN_BIT); | ||
153 | assert(ym & DP_HIDDEN_BIT); | ||
154 | |||
155 | re = xe + ye; | ||
156 | rs = xs ^ ys; | ||
157 | |||
158 | /* shunt to top of word */ | ||
159 | xm <<= 64 - (DP_FBITS + 1); | ||
160 | ym <<= 64 - (DP_FBITS + 1); | ||
161 | |||
162 | /* | ||
163 | * Multiply 32 bits xm, ym to give high 32 bits rm with stickness. | ||
164 | */ | ||
165 | |||
166 | /* 32 * 32 => 64 */ | ||
167 | #define DPXMULT(x, y) ((u64)(x) * (u64)y) | ||
168 | |||
169 | lxm = xm; | ||
170 | hxm = xm >> 32; | ||
171 | lym = ym; | ||
172 | hym = ym >> 32; | ||
173 | |||
174 | lrm = DPXMULT(lxm, lym); | ||
175 | hrm = DPXMULT(hxm, hym); | ||
176 | |||
177 | t = DPXMULT(lxm, hym); | ||
178 | |||
179 | at = lrm + (t << 32); | ||
180 | hrm += at < lrm; | ||
181 | lrm = at; | ||
182 | |||
183 | hrm = hrm + (t >> 32); | ||
184 | |||
185 | t = DPXMULT(hxm, lym); | ||
186 | |||
187 | at = lrm + (t << 32); | ||
188 | hrm += at < lrm; | ||
189 | lrm = at; | ||
190 | |||
191 | hrm = hrm + (t >> 32); | ||
192 | |||
193 | rm = hrm | (lrm != 0); | ||
194 | |||
195 | /* | ||
196 | * Sticky shift down to normal rounding precision. | ||
197 | */ | ||
198 | if ((s64) rm < 0) { | ||
199 | rm = (rm >> (64 - (DP_FBITS + 1 + 3))) | | ||
200 | ((rm << (DP_FBITS + 1 + 3)) != 0); | ||
201 | re++; | ||
202 | } else { | ||
203 | rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) | | ||
204 | ((rm << (DP_FBITS + 1 + 3 + 1)) != 0); | ||
205 | } | ||
206 | assert(rm & (DP_HIDDEN_BIT << 3)); | ||
207 | |||
208 | /* And now the subtraction */ | ||
209 | |||
210 | /* flip sign of r and handle as add */ | ||
211 | rs ^= 1; | ||
212 | |||
213 | assert(zm & DP_HIDDEN_BIT); | ||
214 | |||
215 | /* | ||
216 | * Provide guard,round and stick bit space. | ||
217 | */ | ||
218 | zm <<= 3; | ||
219 | |||
220 | if (ze > re) { | ||
221 | /* | ||
222 | * Have to shift y fraction right to align. | ||
223 | */ | ||
224 | s = ze - re; | ||
225 | rm = XDPSRS(rm, s); | ||
226 | re += s; | ||
227 | } else if (re > ze) { | ||
228 | /* | ||
229 | * Have to shift x fraction right to align. | ||
230 | */ | ||
231 | s = re - ze; | ||
232 | zm = XDPSRS(zm, s); | ||
233 | ze += s; | ||
234 | } | ||
235 | assert(ze == re); | ||
236 | assert(ze <= DP_EMAX); | ||
237 | |||
238 | if (zs == rs) { | ||
239 | /* | ||
240 | * Generate 28 bit result of adding two 27 bit numbers | ||
241 | * leaving result in xm, xs and xe. | ||
242 | */ | ||
243 | zm = zm + rm; | ||
244 | |||
245 | if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */ | ||
246 | zm = XDPSRS1(zm); | ||
247 | ze++; | ||
248 | } | ||
249 | } else { | ||
250 | if (zm >= rm) { | ||
251 | zm = zm - rm; | ||
252 | } else { | ||
253 | zm = rm - zm; | ||
254 | zs = rs; | ||
255 | } | ||
256 | if (zm == 0) | ||
257 | return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD); | ||
258 | |||
259 | /* | ||
260 | * Normalize to rounding precision. | ||
261 | */ | ||
262 | while ((zm >> (DP_FBITS + 3)) == 0) { | ||
263 | zm <<= 1; | ||
264 | ze--; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | return ieee754dp_format(zs, ze, zm); | ||
269 | } | ||
diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c index d0901f03fa19..87d0b44b0614 100644 --- a/arch/mips/math-emu/dp_mul.c +++ b/arch/mips/math-emu/dp_mul.c | |||
@@ -125,7 +125,7 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y) | |||
125 | ym <<= 64 - (DP_FBITS + 1); | 125 | ym <<= 64 - (DP_FBITS + 1); |
126 | 126 | ||
127 | /* | 127 | /* |
128 | * Multiply 32 bits xm, ym to give high 32 bits rm with stickness. | 128 | * Multiply 64 bits xm, ym to give high 64 bits rm with stickness. |
129 | */ | 129 | */ |
130 | 130 | ||
131 | /* 32 * 32 => 64 */ | 131 | /* 32 * 32 => 64 */ |
@@ -163,7 +163,7 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y) | |||
163 | if ((s64) rm < 0) { | 163 | if ((s64) rm < 0) { |
164 | rm = (rm >> (64 - (DP_FBITS + 1 + 3))) | | 164 | rm = (rm >> (64 - (DP_FBITS + 1 + 3))) | |
165 | ((rm << (DP_FBITS + 1 + 3)) != 0); | 165 | ((rm << (DP_FBITS + 1 + 3)) != 0); |
166 | re++; | 166 | re++; |
167 | } else { | 167 | } else { |
168 | rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) | | 168 | rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) | |
169 | ((rm << (DP_FBITS + 1 + 3 + 1)) != 0); | 169 | ((rm << (DP_FBITS + 1 + 3 + 1)) != 0); |
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index 46b964d2b79c..d4ceacd4fa12 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c | |||
@@ -60,7 +60,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
60 | unsigned int rs; | 60 | unsigned int rs; |
61 | s32 v; | 61 | s32 v; |
62 | 62 | ||
63 | rs = (((insn.mm_a_format.rs + 0x1e) & 0xf) + 2); | 63 | rs = (((insn.mm_a_format.rs + 0xe) & 0xf) + 2); |
64 | v = regs->cp0_epc & ~3; | 64 | v = regs->cp0_epc & ~3; |
65 | v += insn.mm_a_format.simmediate << 2; | 65 | v += insn.mm_a_format.simmediate << 2; |
66 | regs->regs[rs] = (long)v; | 66 | regs->regs[rs] = (long)v; |
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c index 47d26c805eac..465a0342ed4c 100644 --- a/arch/mips/math-emu/ieee754dp.c +++ b/arch/mips/math-emu/ieee754dp.c | |||
@@ -54,10 +54,13 @@ union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r) | |||
54 | assert(ieee754dp_issnan(r)); | 54 | assert(ieee754dp_issnan(r)); |
55 | 55 | ||
56 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 56 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
57 | if (ieee754_csr.nan2008) | 57 | if (ieee754_csr.nan2008) { |
58 | DPMANT(r) |= DP_MBIT(DP_FBITS - 1); | 58 | DPMANT(r) |= DP_MBIT(DP_FBITS - 1); |
59 | else | 59 | } else { |
60 | r = ieee754dp_indef(); | 60 | DPMANT(r) &= ~DP_MBIT(DP_FBITS - 1); |
61 | if (!ieee754dp_isnan(r)) | ||
62 | DPMANT(r) |= DP_MBIT(DP_FBITS - 2); | ||
63 | } | ||
61 | 64 | ||
62 | return r; | 65 | return r; |
63 | } | 66 | } |
diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h index e2babd98fee3..9ba023004eb6 100644 --- a/arch/mips/math-emu/ieee754dp.h +++ b/arch/mips/math-emu/ieee754dp.h | |||
@@ -60,6 +60,7 @@ static inline int ieee754dp_finite(union ieee754dp x) | |||
60 | while ((m >> DP_FBITS) == 0) { m <<= 1; e--; } | 60 | while ((m >> DP_FBITS) == 0) { m <<= 1; e--; } |
61 | #define DPDNORMX DPDNORMx(xm, xe) | 61 | #define DPDNORMX DPDNORMx(xm, xe) |
62 | #define DPDNORMY DPDNORMx(ym, ye) | 62 | #define DPDNORMY DPDNORMx(ym, ye) |
63 | #define DPDNORMZ DPDNORMx(zm, ze) | ||
63 | 64 | ||
64 | static inline union ieee754dp builddp(int s, int bx, u64 m) | 65 | static inline union ieee754dp builddp(int s, int bx, u64 m) |
65 | { | 66 | { |
diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h index ed7bb277b3e0..8bc2f6963324 100644 --- a/arch/mips/math-emu/ieee754int.h +++ b/arch/mips/math-emu/ieee754int.h | |||
@@ -55,6 +55,9 @@ static inline int ieee754_class_nan(int xc) | |||
55 | #define COMPYSP \ | 55 | #define COMPYSP \ |
56 | unsigned ym; int ye; int ys; int yc | 56 | unsigned ym; int ye; int ys; int yc |
57 | 57 | ||
58 | #define COMPZSP \ | ||
59 | unsigned zm; int ze; int zs; int zc | ||
60 | |||
58 | #define EXPLODESP(v, vc, vs, ve, vm) \ | 61 | #define EXPLODESP(v, vc, vs, ve, vm) \ |
59 | { \ | 62 | { \ |
60 | vs = SPSIGN(v); \ | 63 | vs = SPSIGN(v); \ |
@@ -81,6 +84,7 @@ static inline int ieee754_class_nan(int xc) | |||
81 | } | 84 | } |
82 | #define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm) | 85 | #define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm) |
83 | #define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym) | 86 | #define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym) |
87 | #define EXPLODEZSP EXPLODESP(z, zc, zs, ze, zm) | ||
84 | 88 | ||
85 | 89 | ||
86 | #define COMPXDP \ | 90 | #define COMPXDP \ |
@@ -89,6 +93,9 @@ static inline int ieee754_class_nan(int xc) | |||
89 | #define COMPYDP \ | 93 | #define COMPYDP \ |
90 | u64 ym; int ye; int ys; int yc | 94 | u64 ym; int ye; int ys; int yc |
91 | 95 | ||
96 | #define COMPZDP \ | ||
97 | u64 zm; int ze; int zs; int zc | ||
98 | |||
92 | #define EXPLODEDP(v, vc, vs, ve, vm) \ | 99 | #define EXPLODEDP(v, vc, vs, ve, vm) \ |
93 | { \ | 100 | { \ |
94 | vm = DPMANT(v); \ | 101 | vm = DPMANT(v); \ |
@@ -115,6 +122,7 @@ static inline int ieee754_class_nan(int xc) | |||
115 | } | 122 | } |
116 | #define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm) | 123 | #define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm) |
117 | #define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym) | 124 | #define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym) |
125 | #define EXPLODEZDP EXPLODEDP(z, zc, zs, ze, zm) | ||
118 | 126 | ||
119 | #define FLUSHDP(v, vc, vs, ve, vm) \ | 127 | #define FLUSHDP(v, vc, vs, ve, vm) \ |
120 | if (vc==IEEE754_CLASS_DNORM) { \ | 128 | if (vc==IEEE754_CLASS_DNORM) { \ |
@@ -140,7 +148,9 @@ static inline int ieee754_class_nan(int xc) | |||
140 | 148 | ||
141 | #define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm) | 149 | #define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm) |
142 | #define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym) | 150 | #define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym) |
151 | #define FLUSHZDP FLUSHDP(z, zc, zs, ze, zm) | ||
143 | #define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm) | 152 | #define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm) |
144 | #define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym) | 153 | #define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym) |
154 | #define FLUSHZSP FLUSHSP(z, zc, zs, ze, zm) | ||
145 | 155 | ||
146 | #endif /* __IEEE754INT_H */ | 156 | #endif /* __IEEE754INT_H */ |
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c index e0b2c450b963..260e68965907 100644 --- a/arch/mips/math-emu/ieee754sp.c +++ b/arch/mips/math-emu/ieee754sp.c | |||
@@ -54,10 +54,13 @@ union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r) | |||
54 | assert(ieee754sp_issnan(r)); | 54 | assert(ieee754sp_issnan(r)); |
55 | 55 | ||
56 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 56 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
57 | if (ieee754_csr.nan2008) | 57 | if (ieee754_csr.nan2008) { |
58 | SPMANT(r) |= SP_MBIT(SP_FBITS - 1); | 58 | SPMANT(r) |= SP_MBIT(SP_FBITS - 1); |
59 | else | 59 | } else { |
60 | r = ieee754sp_indef(); | 60 | SPMANT(r) &= ~SP_MBIT(SP_FBITS - 1); |
61 | if (!ieee754sp_isnan(r)) | ||
62 | SPMANT(r) |= SP_MBIT(SP_FBITS - 2); | ||
63 | } | ||
61 | 64 | ||
62 | return r; | 65 | return r; |
63 | } | 66 | } |
@@ -138,7 +141,8 @@ union ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) | |||
138 | } else { | 141 | } else { |
139 | /* sticky right shift es bits | 142 | /* sticky right shift es bits |
140 | */ | 143 | */ |
141 | SPXSRSXn(es); | 144 | xm = XSPSRS(xm, es); |
145 | xe += es; | ||
142 | assert((xm & (SP_HIDDEN_BIT << 3)) == 0); | 146 | assert((xm & (SP_HIDDEN_BIT << 3)) == 0); |
143 | assert(xe == SP_EMIN); | 147 | assert(xe == SP_EMIN); |
144 | } | 148 | } |
diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h index 374a3f00a589..8476067075fe 100644 --- a/arch/mips/math-emu/ieee754sp.h +++ b/arch/mips/math-emu/ieee754sp.h | |||
@@ -46,25 +46,24 @@ static inline int ieee754sp_finite(union ieee754sp x) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | /* 3bit extended single precision sticky right shift */ | 48 | /* 3bit extended single precision sticky right shift */ |
49 | #define SPXSRSXn(rs) \ | 49 | #define XSPSRS(v, rs) \ |
50 | (xe += rs, \ | 50 | ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0)) |
51 | xm = (rs > (SP_FBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0)) | ||
52 | 51 | ||
53 | #define SPXSRSX1() \ | 52 | #define XSPSRS1(m) \ |
54 | (xe++, (xm = (xm >> 1) | (xm & 1))) | 53 | ((m >> 1) | (m & 1)) |
55 | 54 | ||
56 | #define SPXSRSYn(rs) \ | 55 | #define SPXSRSX1() \ |
57 | (ye+=rs, \ | 56 | (xe++, (xm = XSPSRS1(xm))) |
58 | ym = (rs > (SP_FBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0)) | ||
59 | 57 | ||
60 | #define SPXSRSY1() \ | 58 | #define SPXSRSY1() \ |
61 | (ye++, (ym = (ym >> 1) | (ym & 1))) | 59 | (ye++, (ym = XSPSRS1(ym))) |
62 | 60 | ||
63 | /* convert denormal to normalized with extended exponent */ | 61 | /* convert denormal to normalized with extended exponent */ |
64 | #define SPDNORMx(m,e) \ | 62 | #define SPDNORMx(m,e) \ |
65 | while ((m >> SP_FBITS) == 0) { m <<= 1; e--; } | 63 | while ((m >> SP_FBITS) == 0) { m <<= 1; e--; } |
66 | #define SPDNORMX SPDNORMx(xm, xe) | 64 | #define SPDNORMX SPDNORMx(xm, xe) |
67 | #define SPDNORMY SPDNORMx(ym, ye) | 65 | #define SPDNORMY SPDNORMx(ym, ye) |
66 | #define SPDNORMZ SPDNORMx(zm, ze) | ||
68 | 67 | ||
69 | static inline union ieee754sp buildsp(int s, int bx, unsigned m) | 68 | static inline union ieee754sp buildsp(int s, int bx, unsigned m) |
70 | { | 69 | { |
diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c index f1c87b07d3b4..c55c0c00bca8 100644 --- a/arch/mips/math-emu/sp_add.c +++ b/arch/mips/math-emu/sp_add.c | |||
@@ -132,13 +132,15 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y) | |||
132 | * Have to shift y fraction right to align. | 132 | * Have to shift y fraction right to align. |
133 | */ | 133 | */ |
134 | s = xe - ye; | 134 | s = xe - ye; |
135 | SPXSRSYn(s); | 135 | ym = XSPSRS(ym, s); |
136 | ye += s; | ||
136 | } else if (ye > xe) { | 137 | } else if (ye > xe) { |
137 | /* | 138 | /* |
138 | * Have to shift x fraction right to align. | 139 | * Have to shift x fraction right to align. |
139 | */ | 140 | */ |
140 | s = ye - xe; | 141 | s = ye - xe; |
141 | SPXSRSXn(s); | 142 | xm = XSPSRS(xm, s); |
143 | xe += s; | ||
142 | } | 144 | } |
143 | assert(xe == ye); | 145 | assert(xe == ye); |
144 | assert(xe <= SP_EMAX); | 146 | assert(xe <= SP_EMAX); |
diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c index dd1dd83e34eb..a8cd8b4f235e 100644 --- a/arch/mips/math-emu/sp_maddf.c +++ b/arch/mips/math-emu/sp_maddf.c | |||
@@ -14,8 +14,12 @@ | |||
14 | 14 | ||
15 | #include "ieee754sp.h" | 15 | #include "ieee754sp.h" |
16 | 16 | ||
17 | union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | 17 | enum maddf_flags { |
18 | union ieee754sp y) | 18 | maddf_negate_product = 1 << 0, |
19 | }; | ||
20 | |||
21 | static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, | ||
22 | union ieee754sp y, enum maddf_flags flags) | ||
19 | { | 23 | { |
20 | int re; | 24 | int re; |
21 | int rs; | 25 | int rs; |
@@ -32,15 +36,15 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | |||
32 | 36 | ||
33 | COMPXSP; | 37 | COMPXSP; |
34 | COMPYSP; | 38 | COMPYSP; |
35 | u32 zm; int ze; int zs __maybe_unused; int zc; | 39 | COMPZSP; |
36 | 40 | ||
37 | EXPLODEXSP; | 41 | EXPLODEXSP; |
38 | EXPLODEYSP; | 42 | EXPLODEYSP; |
39 | EXPLODESP(z, zc, zs, ze, zm) | 43 | EXPLODEZSP; |
40 | 44 | ||
41 | FLUSHXSP; | 45 | FLUSHXSP; |
42 | FLUSHYSP; | 46 | FLUSHYSP; |
43 | FLUSHSP(z, zc, zs, ze, zm); | 47 | FLUSHZSP; |
44 | 48 | ||
45 | ieee754_clearcx(); | 49 | ieee754_clearcx(); |
46 | 50 | ||
@@ -49,7 +53,7 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | |||
49 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 53 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
50 | return ieee754sp_nanxcpt(z); | 54 | return ieee754sp_nanxcpt(z); |
51 | case IEEE754_CLASS_DNORM: | 55 | case IEEE754_CLASS_DNORM: |
52 | SPDNORMx(zm, ze); | 56 | SPDNORMZ; |
53 | /* QNAN is handled separately below */ | 57 | /* QNAN is handled separately below */ |
54 | } | 58 | } |
55 | 59 | ||
@@ -154,6 +158,8 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | |||
154 | 158 | ||
155 | re = xe + ye; | 159 | re = xe + ye; |
156 | rs = xs ^ ys; | 160 | rs = xs ^ ys; |
161 | if (flags & maddf_negate_product) | ||
162 | rs ^= 1; | ||
157 | 163 | ||
158 | /* shunt to top of word */ | 164 | /* shunt to top of word */ |
159 | xm <<= 32 - (SP_FBITS + 1); | 165 | xm <<= 32 - (SP_FBITS + 1); |
@@ -208,16 +214,18 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | |||
208 | 214 | ||
209 | if (ze > re) { | 215 | if (ze > re) { |
210 | /* | 216 | /* |
211 | * Have to shift y fraction right to align. | 217 | * Have to shift r fraction right to align. |
212 | */ | 218 | */ |
213 | s = ze - re; | 219 | s = ze - re; |
214 | SPXSRSYn(s); | 220 | rm = XSPSRS(rm, s); |
221 | re += s; | ||
215 | } else if (re > ze) { | 222 | } else if (re > ze) { |
216 | /* | 223 | /* |
217 | * Have to shift x fraction right to align. | 224 | * Have to shift z fraction right to align. |
218 | */ | 225 | */ |
219 | s = re - ze; | 226 | s = re - ze; |
220 | SPXSRSYn(s); | 227 | zm = XSPSRS(zm, s); |
228 | ze += s; | ||
221 | } | 229 | } |
222 | assert(ze == re); | 230 | assert(ze == re); |
223 | assert(ze <= SP_EMAX); | 231 | assert(ze <= SP_EMAX); |
@@ -230,7 +238,8 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | |||
230 | zm = zm + rm; | 238 | zm = zm + rm; |
231 | 239 | ||
232 | if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */ | 240 | if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */ |
233 | SPXSRSX1(); | 241 | zm = XSPSRS1(zm); |
242 | ze++; | ||
234 | } | 243 | } |
235 | } else { | 244 | } else { |
236 | if (zm >= rm) { | 245 | if (zm >= rm) { |
@@ -253,3 +262,15 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | |||
253 | } | 262 | } |
254 | return ieee754sp_format(zs, ze, zm); | 263 | return ieee754sp_format(zs, ze, zm); |
255 | } | 264 | } |
265 | |||
266 | union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | ||
267 | union ieee754sp y) | ||
268 | { | ||
269 | return _sp_maddf(z, x, y, 0); | ||
270 | } | ||
271 | |||
272 | union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, | ||
273 | union ieee754sp y) | ||
274 | { | ||
275 | return _sp_maddf(z, x, y, maddf_negate_product); | ||
276 | } | ||
diff --git a/arch/mips/math-emu/sp_msubf.c b/arch/mips/math-emu/sp_msubf.c deleted file mode 100644 index 81c38b980d69..000000000000 --- a/arch/mips/math-emu/sp_msubf.c +++ /dev/null | |||
@@ -1,258 +0,0 @@ | |||
1 | /* | ||
2 | * IEEE754 floating point arithmetic | ||
3 | * single precision: MSUB.f (Fused Multiply Subtract) | ||
4 | * MSUBF.fmt: FPR[fd] = FPR[fd] - (FPR[fs] x FPR[ft]) | ||
5 | * | ||
6 | * MIPS floating point support | ||
7 | * Copyright (C) 2015 Imagination Technologies, Ltd. | ||
8 | * Author: Markos Chandras <markos.chandras@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 as published by the | ||
12 | * Free Software Foundation; version 2 of the License. | ||
13 | */ | ||
14 | |||
15 | #include "ieee754sp.h" | ||
16 | |||
17 | union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, | ||
18 | union ieee754sp y) | ||
19 | { | ||
20 | int re; | ||
21 | int rs; | ||
22 | unsigned rm; | ||
23 | unsigned short lxm; | ||
24 | unsigned short hxm; | ||
25 | unsigned short lym; | ||
26 | unsigned short hym; | ||
27 | unsigned lrm; | ||
28 | unsigned hrm; | ||
29 | unsigned t; | ||
30 | unsigned at; | ||
31 | int s; | ||
32 | |||
33 | COMPXSP; | ||
34 | COMPYSP; | ||
35 | u32 zm; int ze; int zs __maybe_unused; int zc; | ||
36 | |||
37 | EXPLODEXSP; | ||
38 | EXPLODEYSP; | ||
39 | EXPLODESP(z, zc, zs, ze, zm) | ||
40 | |||
41 | FLUSHXSP; | ||
42 | FLUSHYSP; | ||
43 | FLUSHSP(z, zc, zs, ze, zm); | ||
44 | |||
45 | ieee754_clearcx(); | ||
46 | |||
47 | switch (zc) { | ||
48 | case IEEE754_CLASS_SNAN: | ||
49 | ieee754_setcx(IEEE754_INVALID_OPERATION); | ||
50 | return ieee754sp_nanxcpt(z); | ||
51 | case IEEE754_CLASS_DNORM: | ||
52 | SPDNORMx(zm, ze); | ||
53 | /* QNAN is handled separately below */ | ||
54 | } | ||
55 | |||
56 | switch (CLPAIR(xc, yc)) { | ||
57 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): | ||
58 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): | ||
59 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): | ||
60 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): | ||
61 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): | ||
62 | return ieee754sp_nanxcpt(y); | ||
63 | |||
64 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): | ||
65 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): | ||
66 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): | ||
67 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): | ||
68 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): | ||
69 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): | ||
70 | return ieee754sp_nanxcpt(x); | ||
71 | |||
72 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): | ||
73 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): | ||
74 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): | ||
75 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): | ||
76 | return y; | ||
77 | |||
78 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): | ||
79 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): | ||
80 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): | ||
81 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): | ||
82 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): | ||
83 | return x; | ||
84 | |||
85 | /* | ||
86 | * Infinity handling | ||
87 | */ | ||
88 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): | ||
89 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): | ||
90 | if (zc == IEEE754_CLASS_QNAN) | ||
91 | return z; | ||
92 | ieee754_setcx(IEEE754_INVALID_OPERATION); | ||
93 | return ieee754sp_indef(); | ||
94 | |||
95 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): | ||
96 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): | ||
97 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): | ||
98 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): | ||
99 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): | ||
100 | if (zc == IEEE754_CLASS_QNAN) | ||
101 | return z; | ||
102 | return ieee754sp_inf(xs ^ ys); | ||
103 | |||
104 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): | ||
105 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): | ||
106 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): | ||
107 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): | ||
108 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): | ||
109 | if (zc == IEEE754_CLASS_INF) | ||
110 | return ieee754sp_inf(zs); | ||
111 | /* Multiplication is 0 so just return z */ | ||
112 | return z; | ||
113 | |||
114 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): | ||
115 | SPDNORMX; | ||
116 | |||
117 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): | ||
118 | if (zc == IEEE754_CLASS_QNAN) | ||
119 | return z; | ||
120 | else if (zc == IEEE754_CLASS_INF) | ||
121 | return ieee754sp_inf(zs); | ||
122 | SPDNORMY; | ||
123 | break; | ||
124 | |||
125 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): | ||
126 | if (zc == IEEE754_CLASS_QNAN) | ||
127 | return z; | ||
128 | else if (zc == IEEE754_CLASS_INF) | ||
129 | return ieee754sp_inf(zs); | ||
130 | SPDNORMX; | ||
131 | break; | ||
132 | |||
133 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): | ||
134 | if (zc == IEEE754_CLASS_QNAN) | ||
135 | return z; | ||
136 | else if (zc == IEEE754_CLASS_INF) | ||
137 | return ieee754sp_inf(zs); | ||
138 | /* fall through to real compuation */ | ||
139 | } | ||
140 | |||
141 | /* Finally get to do some computation */ | ||
142 | |||
143 | /* | ||
144 | * Do the multiplication bit first | ||
145 | * | ||
146 | * rm = xm * ym, re = xe + ye basically | ||
147 | * | ||
148 | * At this point xm and ym should have been normalized. | ||
149 | */ | ||
150 | |||
151 | /* rm = xm * ym, re = xe+ye basically */ | ||
152 | assert(xm & SP_HIDDEN_BIT); | ||
153 | assert(ym & SP_HIDDEN_BIT); | ||
154 | |||
155 | re = xe + ye; | ||
156 | rs = xs ^ ys; | ||
157 | |||
158 | /* shunt to top of word */ | ||
159 | xm <<= 32 - (SP_FBITS + 1); | ||
160 | ym <<= 32 - (SP_FBITS + 1); | ||
161 | |||
162 | /* | ||
163 | * Multiply 32 bits xm, ym to give high 32 bits rm with stickness. | ||
164 | */ | ||
165 | lxm = xm & 0xffff; | ||
166 | hxm = xm >> 16; | ||
167 | lym = ym & 0xffff; | ||
168 | hym = ym >> 16; | ||
169 | |||
170 | lrm = lxm * lym; /* 16 * 16 => 32 */ | ||
171 | hrm = hxm * hym; /* 16 * 16 => 32 */ | ||
172 | |||
173 | t = lxm * hym; /* 16 * 16 => 32 */ | ||
174 | at = lrm + (t << 16); | ||
175 | hrm += at < lrm; | ||
176 | lrm = at; | ||
177 | hrm = hrm + (t >> 16); | ||
178 | |||
179 | t = hxm * lym; /* 16 * 16 => 32 */ | ||
180 | at = lrm + (t << 16); | ||
181 | hrm += at < lrm; | ||
182 | lrm = at; | ||
183 | hrm = hrm + (t >> 16); | ||
184 | |||
185 | rm = hrm | (lrm != 0); | ||
186 | |||
187 | /* | ||
188 | * Sticky shift down to normal rounding precision. | ||
189 | */ | ||
190 | if ((int) rm < 0) { | ||
191 | rm = (rm >> (32 - (SP_FBITS + 1 + 3))) | | ||
192 | ((rm << (SP_FBITS + 1 + 3)) != 0); | ||
193 | re++; | ||
194 | } else { | ||
195 | rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) | | ||
196 | ((rm << (SP_FBITS + 1 + 3 + 1)) != 0); | ||
197 | } | ||
198 | assert(rm & (SP_HIDDEN_BIT << 3)); | ||
199 | |||
200 | /* And now the subtraction */ | ||
201 | |||
202 | /* Flip sign of r and handle as add */ | ||
203 | rs ^= 1; | ||
204 | |||
205 | assert(zm & SP_HIDDEN_BIT); | ||
206 | |||
207 | /* | ||
208 | * Provide guard,round and stick bit space. | ||
209 | */ | ||
210 | zm <<= 3; | ||
211 | |||
212 | if (ze > re) { | ||
213 | /* | ||
214 | * Have to shift y fraction right to align. | ||
215 | */ | ||
216 | s = ze - re; | ||
217 | SPXSRSYn(s); | ||
218 | } else if (re > ze) { | ||
219 | /* | ||
220 | * Have to shift x fraction right to align. | ||
221 | */ | ||
222 | s = re - ze; | ||
223 | SPXSRSYn(s); | ||
224 | } | ||
225 | assert(ze == re); | ||
226 | assert(ze <= SP_EMAX); | ||
227 | |||
228 | if (zs == rs) { | ||
229 | /* | ||
230 | * Generate 28 bit result of adding two 27 bit numbers | ||
231 | * leaving result in zm, zs and ze. | ||
232 | */ | ||
233 | zm = zm + rm; | ||
234 | |||
235 | if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */ | ||
236 | SPXSRSX1(); /* shift preserving sticky */ | ||
237 | } | ||
238 | } else { | ||
239 | if (zm >= rm) { | ||
240 | zm = zm - rm; | ||
241 | } else { | ||
242 | zm = rm - zm; | ||
243 | zs = rs; | ||
244 | } | ||
245 | if (zm == 0) | ||
246 | return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); | ||
247 | |||
248 | /* | ||
249 | * Normalize in extended single precision | ||
250 | */ | ||
251 | while ((zm >> (SP_MBITS + 3)) == 0) { | ||
252 | zm <<= 1; | ||
253 | ze--; | ||
254 | } | ||
255 | |||
256 | } | ||
257 | return ieee754sp_format(zs, ze, zm); | ||
258 | } | ||
diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c index ec5f937a8b3e..dc998ed47295 100644 --- a/arch/mips/math-emu/sp_sub.c +++ b/arch/mips/math-emu/sp_sub.c | |||
@@ -134,13 +134,15 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y) | |||
134 | * have to shift y fraction right to align | 134 | * have to shift y fraction right to align |
135 | */ | 135 | */ |
136 | s = xe - ye; | 136 | s = xe - ye; |
137 | SPXSRSYn(s); | 137 | ym = XSPSRS(ym, s); |
138 | ye += s; | ||
138 | } else if (ye > xe) { | 139 | } else if (ye > xe) { |
139 | /* | 140 | /* |
140 | * have to shift x fraction right to align | 141 | * have to shift x fraction right to align |
141 | */ | 142 | */ |
142 | s = ye - xe; | 143 | s = ye - xe; |
143 | SPXSRSXn(s); | 144 | xm = XSPSRS(xm, s); |
145 | xe += s; | ||
144 | } | 146 | } |
145 | assert(xe == ye); | 147 | assert(xe == ye); |
146 | assert(xe <= SP_EMAX); | 148 | assert(xe <= SP_EMAX); |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index caac3d747a90..ef7f925dd1b0 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -77,6 +77,7 @@ static inline void r4k_on_each_cpu(void (*func) (void *info), void *info) | |||
77 | */ | 77 | */ |
78 | static unsigned long icache_size __read_mostly; | 78 | static unsigned long icache_size __read_mostly; |
79 | static unsigned long dcache_size __read_mostly; | 79 | static unsigned long dcache_size __read_mostly; |
80 | static unsigned long vcache_size __read_mostly; | ||
80 | static unsigned long scache_size __read_mostly; | 81 | static unsigned long scache_size __read_mostly; |
81 | 82 | ||
82 | /* | 83 | /* |
@@ -447,6 +448,11 @@ static inline void local_r4k___flush_cache_all(void * args) | |||
447 | r4k_blast_scache(); | 448 | r4k_blast_scache(); |
448 | break; | 449 | break; |
449 | 450 | ||
451 | case CPU_BMIPS5000: | ||
452 | r4k_blast_scache(); | ||
453 | __sync(); | ||
454 | break; | ||
455 | |||
450 | default: | 456 | default: |
451 | r4k_blast_dcache(); | 457 | r4k_blast_dcache(); |
452 | r4k_blast_icache(); | 458 | r4k_blast_icache(); |
@@ -492,7 +498,14 @@ static inline void local_r4k_flush_cache_range(void * args) | |||
492 | if (!(has_valid_asid(vma->vm_mm))) | 498 | if (!(has_valid_asid(vma->vm_mm))) |
493 | return; | 499 | return; |
494 | 500 | ||
495 | r4k_blast_dcache(); | 501 | /* |
502 | * If dcache can alias, we must blast it since mapping is changing. | ||
503 | * If executable, we must ensure any dirty lines are written back far | ||
504 | * enough to be visible to icache. | ||
505 | */ | ||
506 | if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) | ||
507 | r4k_blast_dcache(); | ||
508 | /* If executable, blast stale lines from icache */ | ||
496 | if (exec) | 509 | if (exec) |
497 | r4k_blast_icache(); | 510 | r4k_blast_icache(); |
498 | } | 511 | } |
@@ -502,7 +515,7 @@ static void r4k_flush_cache_range(struct vm_area_struct *vma, | |||
502 | { | 515 | { |
503 | int exec = vma->vm_flags & VM_EXEC; | 516 | int exec = vma->vm_flags & VM_EXEC; |
504 | 517 | ||
505 | if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) | 518 | if (cpu_has_dc_aliases || exec) |
506 | r4k_on_each_cpu(local_r4k_flush_cache_range, vma); | 519 | r4k_on_each_cpu(local_r4k_flush_cache_range, vma); |
507 | } | 520 | } |
508 | 521 | ||
@@ -1148,6 +1161,8 @@ static void probe_pcache(void) | |||
1148 | c->dcache.ways * | 1161 | c->dcache.ways * |
1149 | c->dcache.linesz; | 1162 | c->dcache.linesz; |
1150 | c->dcache.waybit = 0; | 1163 | c->dcache.waybit = 0; |
1164 | if ((prid & PRID_REV_MASK) >= PRID_REV_LOONGSON3A_R2) | ||
1165 | c->options |= MIPS_CPU_PREFETCH; | ||
1151 | break; | 1166 | break; |
1152 | 1167 | ||
1153 | case CPU_CAVIUM_OCTEON3: | 1168 | case CPU_CAVIUM_OCTEON3: |
@@ -1278,6 +1293,8 @@ static void probe_pcache(void) | |||
1278 | case CPU_M5150: | 1293 | case CPU_M5150: |
1279 | case CPU_QEMU_GENERIC: | 1294 | case CPU_QEMU_GENERIC: |
1280 | case CPU_I6400: | 1295 | case CPU_I6400: |
1296 | case CPU_P6600: | ||
1297 | case CPU_M6250: | ||
1281 | if (!(read_c0_config7() & MIPS_CONF7_IAR) && | 1298 | if (!(read_c0_config7() & MIPS_CONF7_IAR) && |
1282 | (c->icache.waysize > PAGE_SIZE)) | 1299 | (c->icache.waysize > PAGE_SIZE)) |
1283 | c->icache.flags |= MIPS_CACHE_ALIASES; | 1300 | c->icache.flags |= MIPS_CACHE_ALIASES; |
@@ -1304,7 +1321,14 @@ static void probe_pcache(void) | |||
1304 | break; | 1321 | break; |
1305 | 1322 | ||
1306 | case CPU_ALCHEMY: | 1323 | case CPU_ALCHEMY: |
1324 | case CPU_I6400: | ||
1325 | c->icache.flags |= MIPS_CACHE_IC_F_DC; | ||
1326 | break; | ||
1327 | |||
1328 | case CPU_BMIPS5000: | ||
1307 | c->icache.flags |= MIPS_CACHE_IC_F_DC; | 1329 | c->icache.flags |= MIPS_CACHE_IC_F_DC; |
1330 | /* Cache aliases are handled in hardware; allow HIGHMEM */ | ||
1331 | c->dcache.flags &= ~MIPS_CACHE_ALIASES; | ||
1308 | break; | 1332 | break; |
1309 | 1333 | ||
1310 | case CPU_LOONGSON2: | 1334 | case CPU_LOONGSON2: |
@@ -1328,6 +1352,31 @@ static void probe_pcache(void) | |||
1328 | c->dcache.linesz); | 1352 | c->dcache.linesz); |
1329 | } | 1353 | } |
1330 | 1354 | ||
1355 | static void probe_vcache(void) | ||
1356 | { | ||
1357 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
1358 | unsigned int config2, lsize; | ||
1359 | |||
1360 | if (current_cpu_type() != CPU_LOONGSON3) | ||
1361 | return; | ||
1362 | |||
1363 | config2 = read_c0_config2(); | ||
1364 | if ((lsize = ((config2 >> 20) & 15))) | ||
1365 | c->vcache.linesz = 2 << lsize; | ||
1366 | else | ||
1367 | c->vcache.linesz = lsize; | ||
1368 | |||
1369 | c->vcache.sets = 64 << ((config2 >> 24) & 15); | ||
1370 | c->vcache.ways = 1 + ((config2 >> 16) & 15); | ||
1371 | |||
1372 | vcache_size = c->vcache.sets * c->vcache.ways * c->vcache.linesz; | ||
1373 | |||
1374 | c->vcache.waybit = 0; | ||
1375 | |||
1376 | pr_info("Unified victim cache %ldkB %s, linesize %d bytes.\n", | ||
1377 | vcache_size >> 10, way_string[c->vcache.ways], c->vcache.linesz); | ||
1378 | } | ||
1379 | |||
1331 | /* | 1380 | /* |
1332 | * If you even _breathe_ on this function, look at the gcc output and make sure | 1381 | * If you even _breathe_ on this function, look at the gcc output and make sure |
1333 | * it does not pop things on and off the stack for the cache sizing loop that | 1382 | * it does not pop things on and off the stack for the cache sizing loop that |
@@ -1650,6 +1699,7 @@ void r4k_cache_init(void) | |||
1650 | struct cpuinfo_mips *c = ¤t_cpu_data; | 1699 | struct cpuinfo_mips *c = ¤t_cpu_data; |
1651 | 1700 | ||
1652 | probe_pcache(); | 1701 | probe_pcache(); |
1702 | probe_vcache(); | ||
1653 | setup_scache(); | 1703 | setup_scache(); |
1654 | 1704 | ||
1655 | r4k_blast_dcache_page_setup(); | 1705 | r4k_blast_dcache_page_setup(); |
@@ -1671,7 +1721,7 @@ void r4k_cache_init(void) | |||
1671 | * This code supports virtually indexed processors and will be | 1721 | * This code supports virtually indexed processors and will be |
1672 | * unnecessarily inefficient on physically indexed processors. | 1722 | * unnecessarily inefficient on physically indexed processors. |
1673 | */ | 1723 | */ |
1674 | if (c->dcache.linesz) | 1724 | if (c->dcache.linesz && cpu_has_dc_aliases) |
1675 | shm_align_mask = max_t( unsigned long, | 1725 | shm_align_mask = max_t( unsigned long, |
1676 | c->dcache.sets * c->dcache.linesz - 1, | 1726 | c->dcache.sets * c->dcache.linesz - 1, |
1677 | PAGE_SIZE - 1); | 1727 | PAGE_SIZE - 1); |
@@ -1744,12 +1794,24 @@ void r4k_cache_init(void) | |||
1744 | flush_icache_range = (void *)b5k_instruction_hazard; | 1794 | flush_icache_range = (void *)b5k_instruction_hazard; |
1745 | local_flush_icache_range = (void *)b5k_instruction_hazard; | 1795 | local_flush_icache_range = (void *)b5k_instruction_hazard; |
1746 | 1796 | ||
1747 | /* Cache aliases are handled in hardware; allow HIGHMEM */ | ||
1748 | current_cpu_data.dcache.flags &= ~MIPS_CACHE_ALIASES; | ||
1749 | 1797 | ||
1750 | /* Optimization: an L2 flush implicitly flushes the L1 */ | 1798 | /* Optimization: an L2 flush implicitly flushes the L1 */ |
1751 | current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES; | 1799 | current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES; |
1752 | break; | 1800 | break; |
1801 | case CPU_LOONGSON3: | ||
1802 | /* Loongson-3 maintains cache coherency by hardware */ | ||
1803 | __flush_cache_all = cache_noop; | ||
1804 | __flush_cache_vmap = cache_noop; | ||
1805 | __flush_cache_vunmap = cache_noop; | ||
1806 | __flush_kernel_vmap_range = (void *)cache_noop; | ||
1807 | flush_cache_mm = (void *)cache_noop; | ||
1808 | flush_cache_page = (void *)cache_noop; | ||
1809 | flush_cache_range = (void *)cache_noop; | ||
1810 | flush_cache_sigtramp = (void *)cache_noop; | ||
1811 | flush_icache_all = (void *)cache_noop; | ||
1812 | flush_data_cache_page = (void *)cache_noop; | ||
1813 | local_flush_data_cache_page = (void *)cache_noop; | ||
1814 | break; | ||
1753 | } | 1815 | } |
1754 | } | 1816 | } |
1755 | 1817 | ||
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 3f159caf6dbc..bf04c6c479a4 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | 17 | ||
18 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
19 | #include <asm/highmem.h> | ||
19 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
20 | #include <asm/cpu.h> | 21 | #include <asm/cpu.h> |
21 | #include <asm/cpu-features.h> | 22 | #include <asm/cpu-features.h> |
@@ -83,8 +84,6 @@ void __flush_dcache_page(struct page *page) | |||
83 | struct address_space *mapping = page_mapping(page); | 84 | struct address_space *mapping = page_mapping(page); |
84 | unsigned long addr; | 85 | unsigned long addr; |
85 | 86 | ||
86 | if (PageHighMem(page)) | ||
87 | return; | ||
88 | if (mapping && !mapping_mapped(mapping)) { | 87 | if (mapping && !mapping_mapped(mapping)) { |
89 | SetPageDcacheDirty(page); | 88 | SetPageDcacheDirty(page); |
90 | return; | 89 | return; |
@@ -95,8 +94,15 @@ void __flush_dcache_page(struct page *page) | |||
95 | * case is for exec env/arg pages and those are %99 certainly going to | 94 | * case is for exec env/arg pages and those are %99 certainly going to |
96 | * get faulted into the tlb (and thus flushed) anyways. | 95 | * get faulted into the tlb (and thus flushed) anyways. |
97 | */ | 96 | */ |
98 | addr = (unsigned long) page_address(page); | 97 | if (PageHighMem(page)) |
98 | addr = (unsigned long)kmap_atomic(page); | ||
99 | else | ||
100 | addr = (unsigned long)page_address(page); | ||
101 | |||
99 | flush_data_cache_page(addr); | 102 | flush_data_cache_page(addr); |
103 | |||
104 | if (PageHighMem(page)) | ||
105 | __kunmap_atomic((void *)addr); | ||
100 | } | 106 | } |
101 | 107 | ||
102 | EXPORT_SYMBOL(__flush_dcache_page); | 108 | EXPORT_SYMBOL(__flush_dcache_page); |
@@ -119,33 +125,28 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr) | |||
119 | 125 | ||
120 | EXPORT_SYMBOL(__flush_anon_page); | 126 | EXPORT_SYMBOL(__flush_anon_page); |
121 | 127 | ||
122 | void __flush_icache_page(struct vm_area_struct *vma, struct page *page) | 128 | void __update_cache(unsigned long address, pte_t pte) |
123 | { | ||
124 | unsigned long addr; | ||
125 | |||
126 | if (PageHighMem(page)) | ||
127 | return; | ||
128 | |||
129 | addr = (unsigned long) page_address(page); | ||
130 | flush_data_cache_page(addr); | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(__flush_icache_page); | ||
133 | |||
134 | void __update_cache(struct vm_area_struct *vma, unsigned long address, | ||
135 | pte_t pte) | ||
136 | { | 129 | { |
137 | struct page *page; | 130 | struct page *page; |
138 | unsigned long pfn, addr; | 131 | unsigned long pfn, addr; |
139 | int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc; | 132 | int exec = !pte_no_exec(pte) && !cpu_has_ic_fills_f_dc; |
140 | 133 | ||
141 | pfn = pte_pfn(pte); | 134 | pfn = pte_pfn(pte); |
142 | if (unlikely(!pfn_valid(pfn))) | 135 | if (unlikely(!pfn_valid(pfn))) |
143 | return; | 136 | return; |
144 | page = pfn_to_page(pfn); | 137 | page = pfn_to_page(pfn); |
145 | if (page_mapping(page) && Page_dcache_dirty(page)) { | 138 | if (Page_dcache_dirty(page)) { |
146 | addr = (unsigned long) page_address(page); | 139 | if (PageHighMem(page)) |
140 | addr = (unsigned long)kmap_atomic(page); | ||
141 | else | ||
142 | addr = (unsigned long)page_address(page); | ||
143 | |||
147 | if (exec || pages_do_alias(addr, address & PAGE_MASK)) | 144 | if (exec || pages_do_alias(addr, address & PAGE_MASK)) |
148 | flush_data_cache_page(addr); | 145 | flush_data_cache_page(addr); |
146 | |||
147 | if (PageHighMem(page)) | ||
148 | __kunmap_atomic((void *)addr); | ||
149 | |||
149 | ClearPageDcacheDirty(page); | 150 | ClearPageDcacheDirty(page); |
150 | } | 151 | } |
151 | } | 152 | } |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 730d394ce5f0..cb557d28cb21 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -88,19 +88,20 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) | |||
88 | else | 88 | else |
89 | #endif | 89 | #endif |
90 | #if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA) | 90 | #if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA) |
91 | if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) | 91 | if (dev == NULL || dev->coherent_dma_mask < DMA_BIT_MASK(32)) |
92 | dma_flag = __GFP_DMA; | 92 | dma_flag = __GFP_DMA; |
93 | else if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) | 93 | else if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) |
94 | dma_flag = __GFP_DMA32; | 94 | dma_flag = __GFP_DMA32; |
95 | else | 95 | else |
96 | #endif | 96 | #endif |
97 | #if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA) | 97 | #if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA) |
98 | if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) | 98 | if (dev == NULL || dev->coherent_dma_mask < DMA_BIT_MASK(64)) |
99 | dma_flag = __GFP_DMA32; | 99 | dma_flag = __GFP_DMA32; |
100 | else | 100 | else |
101 | #endif | 101 | #endif |
102 | #if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32) | 102 | #if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32) |
103 | if (dev->coherent_dma_mask < DMA_BIT_MASK(sizeof(phys_addr_t) * 8)) | 103 | if (dev == NULL || |
104 | dev->coherent_dma_mask < DMA_BIT_MASK(sizeof(phys_addr_t) * 8)) | ||
104 | dma_flag = __GFP_DMA; | 105 | dma_flag = __GFP_DMA; |
105 | else | 106 | else |
106 | #endif | 107 | #endif |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 7e5fa0938c21..9b58eb5fd0d5 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -98,8 +98,10 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | |||
98 | idx += in_interrupt() ? FIX_N_COLOURS : 0; | 98 | idx += in_interrupt() ? FIX_N_COLOURS : 0; |
99 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); | 99 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); |
100 | pte = mk_pte(page, prot); | 100 | pte = mk_pte(page, prot); |
101 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 101 | #if defined(CONFIG_XPA) |
102 | entrylo = pte_to_entrylo(pte.pte_high); | 102 | entrylo = pte_to_entrylo(pte.pte_high); |
103 | #elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | ||
104 | entrylo = pte.pte_high; | ||
103 | #else | 105 | #else |
104 | entrylo = pte_to_entrylo(pte_val(pte)); | 106 | entrylo = pte_to_entrylo(pte_val(pte)); |
105 | #endif | 107 | #endif |
@@ -110,9 +112,11 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | |||
110 | write_c0_entrylo0(entrylo); | 112 | write_c0_entrylo0(entrylo); |
111 | write_c0_entrylo1(entrylo); | 113 | write_c0_entrylo1(entrylo); |
112 | #ifdef CONFIG_XPA | 114 | #ifdef CONFIG_XPA |
113 | entrylo = (pte.pte_low & _PFNX_MASK); | 115 | if (cpu_has_xpa) { |
114 | writex_c0_entrylo0(entrylo); | 116 | entrylo = (pte.pte_low & _PFNX_MASK); |
115 | writex_c0_entrylo1(entrylo); | 117 | writex_c0_entrylo0(entrylo); |
118 | writex_c0_entrylo1(entrylo); | ||
119 | } | ||
116 | #endif | 120 | #endif |
117 | tlbidx = read_c0_wired(); | 121 | tlbidx = read_c0_wired(); |
118 | write_c0_wired(tlbidx + 1); | 122 | write_c0_wired(tlbidx + 1); |
@@ -196,7 +200,7 @@ void copy_to_user_page(struct vm_area_struct *vma, | |||
196 | if (cpu_has_dc_aliases) | 200 | if (cpu_has_dc_aliases) |
197 | SetPageDcacheDirty(page); | 201 | SetPageDcacheDirty(page); |
198 | } | 202 | } |
199 | if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) | 203 | if (vma->vm_flags & VM_EXEC) |
200 | flush_cache_page(vma, vaddr, page_to_pfn(page)); | 204 | flush_cache_page(vma, vaddr, page_to_pfn(page)); |
201 | } | 205 | } |
202 | 206 | ||
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index 885d73ffd6fb..c41953ca6605 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c | |||
@@ -188,6 +188,15 @@ static void set_prefetch_parameters(void) | |||
188 | } | 188 | } |
189 | break; | 189 | break; |
190 | 190 | ||
191 | case CPU_LOONGSON3: | ||
192 | /* Loongson-3 only support the Pref_Load/Pref_Store. */ | ||
193 | pref_bias_clear_store = 128; | ||
194 | pref_bias_copy_load = 128; | ||
195 | pref_bias_copy_store = 128; | ||
196 | pref_src_mode = Pref_Load; | ||
197 | pref_dst_mode = Pref_Store; | ||
198 | break; | ||
199 | |||
191 | default: | 200 | default: |
192 | pref_bias_clear_store = 128; | 201 | pref_bias_clear_store = 128; |
193 | pref_bias_copy_load = 256; | 202 | pref_bias_copy_load = 256; |
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 91dec32c77b7..286a4d5a1884 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c | |||
@@ -141,6 +141,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c) | |||
141 | case CPU_P5600: | 141 | case CPU_P5600: |
142 | case CPU_BMIPS5000: | 142 | case CPU_BMIPS5000: |
143 | case CPU_QEMU_GENERIC: | 143 | case CPU_QEMU_GENERIC: |
144 | case CPU_P6600: | ||
144 | if (config2 & (1 << 12)) | 145 | if (config2 & (1 << 12)) |
145 | return 0; | 146 | return 0; |
146 | } | 147 | } |
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index b4f366f7c0f5..1290b995695d 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c | |||
@@ -43,7 +43,7 @@ static void local_flush_tlb_from(int entry) | |||
43 | { | 43 | { |
44 | unsigned long old_ctx; | 44 | unsigned long old_ctx; |
45 | 45 | ||
46 | old_ctx = read_c0_entryhi() & ASID_MASK; | 46 | old_ctx = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data); |
47 | write_c0_entrylo0(0); | 47 | write_c0_entrylo0(0); |
48 | while (entry < current_cpu_data.tlbsize) { | 48 | while (entry < current_cpu_data.tlbsize) { |
49 | write_c0_index(entry << 8); | 49 | write_c0_index(entry << 8); |
@@ -81,6 +81,7 @@ void local_flush_tlb_mm(struct mm_struct *mm) | |||
81 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | 81 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, |
82 | unsigned long end) | 82 | unsigned long end) |
83 | { | 83 | { |
84 | unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data); | ||
84 | struct mm_struct *mm = vma->vm_mm; | 85 | struct mm_struct *mm = vma->vm_mm; |
85 | int cpu = smp_processor_id(); | 86 | int cpu = smp_processor_id(); |
86 | 87 | ||
@@ -89,13 +90,13 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
89 | 90 | ||
90 | #ifdef DEBUG_TLB | 91 | #ifdef DEBUG_TLB |
91 | printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", | 92 | printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", |
92 | cpu_context(cpu, mm) & ASID_MASK, start, end); | 93 | cpu_context(cpu, mm) & asid_mask, start, end); |
93 | #endif | 94 | #endif |
94 | local_irq_save(flags); | 95 | local_irq_save(flags); |
95 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 96 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
96 | if (size <= current_cpu_data.tlbsize) { | 97 | if (size <= current_cpu_data.tlbsize) { |
97 | int oldpid = read_c0_entryhi() & ASID_MASK; | 98 | int oldpid = read_c0_entryhi() & asid_mask; |
98 | int newpid = cpu_context(cpu, mm) & ASID_MASK; | 99 | int newpid = cpu_context(cpu, mm) & asid_mask; |
99 | 100 | ||
100 | start &= PAGE_MASK; | 101 | start &= PAGE_MASK; |
101 | end += PAGE_SIZE - 1; | 102 | end += PAGE_SIZE - 1; |
@@ -159,6 +160,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
159 | 160 | ||
160 | void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | 161 | void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) |
161 | { | 162 | { |
163 | unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data); | ||
162 | int cpu = smp_processor_id(); | 164 | int cpu = smp_processor_id(); |
163 | 165 | ||
164 | if (cpu_context(cpu, vma->vm_mm) != 0) { | 166 | if (cpu_context(cpu, vma->vm_mm) != 0) { |
@@ -168,10 +170,10 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
168 | #ifdef DEBUG_TLB | 170 | #ifdef DEBUG_TLB |
169 | printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page); | 171 | printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page); |
170 | #endif | 172 | #endif |
171 | newpid = cpu_context(cpu, vma->vm_mm) & ASID_MASK; | 173 | newpid = cpu_context(cpu, vma->vm_mm) & asid_mask; |
172 | page &= PAGE_MASK; | 174 | page &= PAGE_MASK; |
173 | local_irq_save(flags); | 175 | local_irq_save(flags); |
174 | oldpid = read_c0_entryhi() & ASID_MASK; | 176 | oldpid = read_c0_entryhi() & asid_mask; |
175 | write_c0_entryhi(page | newpid); | 177 | write_c0_entryhi(page | newpid); |
176 | BARRIER; | 178 | BARRIER; |
177 | tlb_probe(); | 179 | tlb_probe(); |
@@ -190,6 +192,7 @@ finish: | |||
190 | 192 | ||
191 | void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) | 193 | void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) |
192 | { | 194 | { |
195 | unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data); | ||
193 | unsigned long flags; | 196 | unsigned long flags; |
194 | int idx, pid; | 197 | int idx, pid; |
195 | 198 | ||
@@ -199,10 +202,10 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) | |||
199 | if (current->active_mm != vma->vm_mm) | 202 | if (current->active_mm != vma->vm_mm) |
200 | return; | 203 | return; |
201 | 204 | ||
202 | pid = read_c0_entryhi() & ASID_MASK; | 205 | pid = read_c0_entryhi() & asid_mask; |
203 | 206 | ||
204 | #ifdef DEBUG_TLB | 207 | #ifdef DEBUG_TLB |
205 | if ((pid != (cpu_context(cpu, vma->vm_mm) & ASID_MASK)) || (cpu_context(cpu, vma->vm_mm) == 0)) { | 208 | if ((pid != (cpu_context(cpu, vma->vm_mm) & asid_mask)) || (cpu_context(cpu, vma->vm_mm) == 0)) { |
206 | printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", | 209 | printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", |
207 | (cpu_context(cpu, vma->vm_mm)), pid); | 210 | (cpu_context(cpu, vma->vm_mm)), pid); |
208 | } | 211 | } |
@@ -228,6 +231,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) | |||
228 | void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | 231 | void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, |
229 | unsigned long entryhi, unsigned long pagemask) | 232 | unsigned long entryhi, unsigned long pagemask) |
230 | { | 233 | { |
234 | unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data); | ||
231 | unsigned long flags; | 235 | unsigned long flags; |
232 | unsigned long old_ctx; | 236 | unsigned long old_ctx; |
233 | static unsigned long wired = 0; | 237 | static unsigned long wired = 0; |
@@ -243,7 +247,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
243 | 247 | ||
244 | local_irq_save(flags); | 248 | local_irq_save(flags); |
245 | /* Save old context and create impossible VPN2 value */ | 249 | /* Save old context and create impossible VPN2 value */ |
246 | old_ctx = read_c0_entryhi() & ASID_MASK; | 250 | old_ctx = read_c0_entryhi() & asid_mask; |
247 | old_pagemask = read_c0_pagemask(); | 251 | old_pagemask = read_c0_pagemask(); |
248 | w = read_c0_wired(); | 252 | w = read_c0_wired(); |
249 | write_c0_wired(w + 1); | 253 | write_c0_wired(w + 1); |
@@ -266,7 +270,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
266 | #endif | 270 | #endif |
267 | 271 | ||
268 | local_irq_save(flags); | 272 | local_irq_save(flags); |
269 | old_ctx = read_c0_entryhi() & ASID_MASK; | 273 | old_ctx = read_c0_entryhi() & asid_mask; |
270 | write_c0_entrylo0(entrylo0); | 274 | write_c0_entrylo0(entrylo0); |
271 | write_c0_entryhi(entryhi); | 275 | write_c0_entryhi(entryhi); |
272 | write_c0_index(wired); | 276 | write_c0_index(wired); |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index c17d7627f872..5a5c7fec645e 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -28,25 +28,28 @@ | |||
28 | extern void build_tlb_refill_handler(void); | 28 | extern void build_tlb_refill_handler(void); |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * LOONGSON2/3 has a 4 entry itlb which is a subset of dtlb, | 31 | * LOONGSON-2 has a 4 entry itlb which is a subset of jtlb, LOONGSON-3 has |
32 | * unfortunately, itlb is not totally transparent to software. | 32 | * a 4 entry itlb and a 4 entry dtlb which are subsets of jtlb. Unfortunately, |
33 | * itlb/dtlb are not totally transparent to software. | ||
33 | */ | 34 | */ |
34 | static inline void flush_itlb(void) | 35 | static inline void flush_micro_tlb(void) |
35 | { | 36 | { |
36 | switch (current_cpu_type()) { | 37 | switch (current_cpu_type()) { |
37 | case CPU_LOONGSON2: | 38 | case CPU_LOONGSON2: |
39 | write_c0_diag(LOONGSON_DIAG_ITLB); | ||
40 | break; | ||
38 | case CPU_LOONGSON3: | 41 | case CPU_LOONGSON3: |
39 | write_c0_diag(4); | 42 | write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB); |
40 | break; | 43 | break; |
41 | default: | 44 | default: |
42 | break; | 45 | break; |
43 | } | 46 | } |
44 | } | 47 | } |
45 | 48 | ||
46 | static inline void flush_itlb_vm(struct vm_area_struct *vma) | 49 | static inline void flush_micro_tlb_vm(struct vm_area_struct *vma) |
47 | { | 50 | { |
48 | if (vma->vm_flags & VM_EXEC) | 51 | if (vma->vm_flags & VM_EXEC) |
49 | flush_itlb(); | 52 | flush_micro_tlb(); |
50 | } | 53 | } |
51 | 54 | ||
52 | void local_flush_tlb_all(void) | 55 | void local_flush_tlb_all(void) |
@@ -93,7 +96,7 @@ void local_flush_tlb_all(void) | |||
93 | tlbw_use_hazard(); | 96 | tlbw_use_hazard(); |
94 | write_c0_entryhi(old_ctx); | 97 | write_c0_entryhi(old_ctx); |
95 | htw_start(); | 98 | htw_start(); |
96 | flush_itlb(); | 99 | flush_micro_tlb(); |
97 | local_irq_restore(flags); | 100 | local_irq_restore(flags); |
98 | } | 101 | } |
99 | EXPORT_SYMBOL(local_flush_tlb_all); | 102 | EXPORT_SYMBOL(local_flush_tlb_all); |
@@ -159,7 +162,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
159 | } else { | 162 | } else { |
160 | drop_mmu_context(mm, cpu); | 163 | drop_mmu_context(mm, cpu); |
161 | } | 164 | } |
162 | flush_itlb(); | 165 | flush_micro_tlb(); |
163 | local_irq_restore(flags); | 166 | local_irq_restore(flags); |
164 | } | 167 | } |
165 | } | 168 | } |
@@ -205,7 +208,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
205 | } else { | 208 | } else { |
206 | local_flush_tlb_all(); | 209 | local_flush_tlb_all(); |
207 | } | 210 | } |
208 | flush_itlb(); | 211 | flush_micro_tlb(); |
209 | local_irq_restore(flags); | 212 | local_irq_restore(flags); |
210 | } | 213 | } |
211 | 214 | ||
@@ -240,7 +243,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
240 | finish: | 243 | finish: |
241 | write_c0_entryhi(oldpid); | 244 | write_c0_entryhi(oldpid); |
242 | htw_start(); | 245 | htw_start(); |
243 | flush_itlb_vm(vma); | 246 | flush_micro_tlb_vm(vma); |
244 | local_irq_restore(flags); | 247 | local_irq_restore(flags); |
245 | } | 248 | } |
246 | } | 249 | } |
@@ -274,7 +277,7 @@ void local_flush_tlb_one(unsigned long page) | |||
274 | } | 277 | } |
275 | write_c0_entryhi(oldpid); | 278 | write_c0_entryhi(oldpid); |
276 | htw_start(); | 279 | htw_start(); |
277 | flush_itlb(); | 280 | flush_micro_tlb(); |
278 | local_irq_restore(flags); | 281 | local_irq_restore(flags); |
279 | } | 282 | } |
280 | 283 | ||
@@ -301,7 +304,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
301 | local_irq_save(flags); | 304 | local_irq_save(flags); |
302 | 305 | ||
303 | htw_stop(); | 306 | htw_stop(); |
304 | pid = read_c0_entryhi() & ASID_MASK; | 307 | pid = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data); |
305 | address &= (PAGE_MASK << 1); | 308 | address &= (PAGE_MASK << 1); |
306 | write_c0_entryhi(address | pid); | 309 | write_c0_entryhi(address | pid); |
307 | pgdp = pgd_offset(vma->vm_mm, address); | 310 | pgdp = pgd_offset(vma->vm_mm, address); |
@@ -336,10 +339,12 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
336 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 339 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
337 | #ifdef CONFIG_XPA | 340 | #ifdef CONFIG_XPA |
338 | write_c0_entrylo0(pte_to_entrylo(ptep->pte_high)); | 341 | write_c0_entrylo0(pte_to_entrylo(ptep->pte_high)); |
339 | writex_c0_entrylo0(ptep->pte_low & _PFNX_MASK); | 342 | if (cpu_has_xpa) |
343 | writex_c0_entrylo0(ptep->pte_low & _PFNX_MASK); | ||
340 | ptep++; | 344 | ptep++; |
341 | write_c0_entrylo1(pte_to_entrylo(ptep->pte_high)); | 345 | write_c0_entrylo1(pte_to_entrylo(ptep->pte_high)); |
342 | writex_c0_entrylo1(ptep->pte_low & _PFNX_MASK); | 346 | if (cpu_has_xpa) |
347 | writex_c0_entrylo1(ptep->pte_low & _PFNX_MASK); | ||
343 | #else | 348 | #else |
344 | write_c0_entrylo0(ptep->pte_high); | 349 | write_c0_entrylo0(ptep->pte_high); |
345 | ptep++; | 350 | ptep++; |
@@ -357,7 +362,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
357 | } | 362 | } |
358 | tlbw_use_hazard(); | 363 | tlbw_use_hazard(); |
359 | htw_start(); | 364 | htw_start(); |
360 | flush_itlb_vm(vma); | 365 | flush_micro_tlb_vm(vma); |
361 | local_irq_restore(flags); | 366 | local_irq_restore(flags); |
362 | } | 367 | } |
363 | 368 | ||
diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c index 138a2ec7cc6b..e86e2e55ad3e 100644 --- a/arch/mips/mm/tlb-r8k.c +++ b/arch/mips/mm/tlb-r8k.c | |||
@@ -194,7 +194,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
194 | if (current->active_mm != vma->vm_mm) | 194 | if (current->active_mm != vma->vm_mm) |
195 | return; | 195 | return; |
196 | 196 | ||
197 | pid = read_c0_entryhi() & ASID_MASK; | 197 | pid = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data); |
198 | 198 | ||
199 | local_irq_save(flags); | 199 | local_irq_save(flags); |
200 | address &= PAGE_MASK; | 200 | address &= PAGE_MASK; |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 84c6e3fda84a..274da90adf0d 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -234,20 +234,16 @@ static void output_pgtable_bits_defines(void) | |||
234 | pr_debug("\n"); | 234 | pr_debug("\n"); |
235 | 235 | ||
236 | pr_define("_PAGE_PRESENT_SHIFT %d\n", _PAGE_PRESENT_SHIFT); | 236 | pr_define("_PAGE_PRESENT_SHIFT %d\n", _PAGE_PRESENT_SHIFT); |
237 | pr_define("_PAGE_READ_SHIFT %d\n", _PAGE_READ_SHIFT); | 237 | pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT); |
238 | pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT); | 238 | pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT); |
239 | pr_define("_PAGE_ACCESSED_SHIFT %d\n", _PAGE_ACCESSED_SHIFT); | 239 | pr_define("_PAGE_ACCESSED_SHIFT %d\n", _PAGE_ACCESSED_SHIFT); |
240 | pr_define("_PAGE_MODIFIED_SHIFT %d\n", _PAGE_MODIFIED_SHIFT); | 240 | pr_define("_PAGE_MODIFIED_SHIFT %d\n", _PAGE_MODIFIED_SHIFT); |
241 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 241 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
242 | pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); | 242 | pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); |
243 | #endif | 243 | #endif |
244 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) | ||
245 | if (cpu_has_rixi) { | ||
246 | #ifdef _PAGE_NO_EXEC_SHIFT | 244 | #ifdef _PAGE_NO_EXEC_SHIFT |
245 | if (cpu_has_rixi) | ||
247 | pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT); | 246 | pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT); |
248 | pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT); | ||
249 | #endif | ||
250 | } | ||
251 | #endif | 247 | #endif |
252 | pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT); | 248 | pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT); |
253 | pr_define("_PAGE_VALID_SHIFT %d\n", _PAGE_VALID_SHIFT); | 249 | pr_define("_PAGE_VALID_SHIFT %d\n", _PAGE_VALID_SHIFT); |
@@ -284,7 +280,12 @@ static inline void dump_handler(const char *symbol, const u32 *handler, int coun | |||
284 | #define C0_ENTRYLO1 3, 0 | 280 | #define C0_ENTRYLO1 3, 0 |
285 | #define C0_CONTEXT 4, 0 | 281 | #define C0_CONTEXT 4, 0 |
286 | #define C0_PAGEMASK 5, 0 | 282 | #define C0_PAGEMASK 5, 0 |
283 | #define C0_PWBASE 5, 5 | ||
284 | #define C0_PWFIELD 5, 6 | ||
285 | #define C0_PWSIZE 5, 7 | ||
286 | #define C0_PWCTL 6, 6 | ||
287 | #define C0_BADVADDR 8, 0 | 287 | #define C0_BADVADDR 8, 0 |
288 | #define C0_PGD 9, 7 | ||
288 | #define C0_ENTRYHI 10, 0 | 289 | #define C0_ENTRYHI 10, 0 |
289 | #define C0_EPC 14, 0 | 290 | #define C0_EPC 14, 0 |
290 | #define C0_XCONTEXT 20, 0 | 291 | #define C0_XCONTEXT 20, 0 |
@@ -630,6 +631,11 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l, | |||
630 | static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, | 631 | static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, |
631 | unsigned int reg) | 632 | unsigned int reg) |
632 | { | 633 | { |
634 | if (_PAGE_GLOBAL_SHIFT == 0) { | ||
635 | /* pte_t is already in EntryLo format */ | ||
636 | return; | ||
637 | } | ||
638 | |||
633 | if (cpu_has_rixi && _PAGE_NO_EXEC) { | 639 | if (cpu_has_rixi && _PAGE_NO_EXEC) { |
634 | if (fill_includes_sw_bits) { | 640 | if (fill_includes_sw_bits) { |
635 | UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); | 641 | UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); |
@@ -808,7 +814,10 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, | |||
808 | 814 | ||
809 | if (pgd_reg != -1) { | 815 | if (pgd_reg != -1) { |
810 | /* pgd is in pgd_reg */ | 816 | /* pgd is in pgd_reg */ |
811 | UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg); | 817 | if (cpu_has_ldpte) |
818 | UASM_i_MFC0(p, ptr, C0_PWBASE); | ||
819 | else | ||
820 | UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg); | ||
812 | } else { | 821 | } else { |
813 | #if defined(CONFIG_MIPS_PGD_C0_CONTEXT) | 822 | #if defined(CONFIG_MIPS_PGD_C0_CONTEXT) |
814 | /* | 823 | /* |
@@ -1007,39 +1016,40 @@ static void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) | |||
1007 | 1016 | ||
1008 | static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) | 1017 | static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) |
1009 | { | 1018 | { |
1010 | /* | 1019 | int pte_off_even = 0; |
1011 | * 64bit address support (36bit on a 32bit CPU) in a 32bit | 1020 | int pte_off_odd = sizeof(pte_t); |
1012 | * Kernel is a special case. Only a few CPUs use it. | ||
1013 | */ | ||
1014 | if (config_enabled(CONFIG_PHYS_ADDR_T_64BIT) && !cpu_has_64bits) { | ||
1015 | int pte_off_even = sizeof(pte_t) / 2; | ||
1016 | int pte_off_odd = pte_off_even + sizeof(pte_t); | ||
1017 | #ifdef CONFIG_XPA | ||
1018 | const int scratch = 1; /* Our extra working register */ | ||
1019 | 1021 | ||
1020 | uasm_i_addu(p, scratch, 0, ptep); | 1022 | #if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_PHYS_ADDR_T_64BIT) |
1023 | /* The low 32 bits of EntryLo is stored in pte_high */ | ||
1024 | pte_off_even += offsetof(pte_t, pte_high); | ||
1025 | pte_off_odd += offsetof(pte_t, pte_high); | ||
1021 | #endif | 1026 | #endif |
1027 | |||
1028 | if (config_enabled(CONFIG_XPA)) { | ||
1022 | uasm_i_lw(p, tmp, pte_off_even, ptep); /* even pte */ | 1029 | uasm_i_lw(p, tmp, pte_off_even, ptep); /* even pte */ |
1023 | uasm_i_lw(p, ptep, pte_off_odd, ptep); /* odd pte */ | ||
1024 | UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); | 1030 | UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); |
1025 | UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); | ||
1026 | UASM_i_MTC0(p, tmp, C0_ENTRYLO0); | 1031 | UASM_i_MTC0(p, tmp, C0_ENTRYLO0); |
1027 | UASM_i_MTC0(p, ptep, C0_ENTRYLO1); | 1032 | |
1028 | #ifdef CONFIG_XPA | 1033 | if (cpu_has_xpa && !mips_xpa_disabled) { |
1029 | uasm_i_lw(p, tmp, 0, scratch); | 1034 | uasm_i_lw(p, tmp, 0, ptep); |
1030 | uasm_i_lw(p, ptep, sizeof(pte_t), scratch); | 1035 | uasm_i_ext(p, tmp, tmp, 0, 24); |
1031 | uasm_i_lui(p, scratch, 0xff); | 1036 | uasm_i_mthc0(p, tmp, C0_ENTRYLO0); |
1032 | uasm_i_ori(p, scratch, scratch, 0xffff); | 1037 | } |
1033 | uasm_i_and(p, tmp, scratch, tmp); | 1038 | |
1034 | uasm_i_and(p, ptep, scratch, ptep); | 1039 | uasm_i_lw(p, tmp, pte_off_odd, ptep); /* odd pte */ |
1035 | uasm_i_mthc0(p, tmp, C0_ENTRYLO0); | 1040 | UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); |
1036 | uasm_i_mthc0(p, ptep, C0_ENTRYLO1); | 1041 | UASM_i_MTC0(p, tmp, C0_ENTRYLO1); |
1037 | #endif | 1042 | |
1043 | if (cpu_has_xpa && !mips_xpa_disabled) { | ||
1044 | uasm_i_lw(p, tmp, sizeof(pte_t), ptep); | ||
1045 | uasm_i_ext(p, tmp, tmp, 0, 24); | ||
1046 | uasm_i_mthc0(p, tmp, C0_ENTRYLO1); | ||
1047 | } | ||
1038 | return; | 1048 | return; |
1039 | } | 1049 | } |
1040 | 1050 | ||
1041 | UASM_i_LW(p, tmp, 0, ptep); /* get even pte */ | 1051 | UASM_i_LW(p, tmp, pte_off_even, ptep); /* get even pte */ |
1042 | UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ | 1052 | UASM_i_LW(p, ptep, pte_off_odd, ptep); /* get odd pte */ |
1043 | if (r45k_bvahwbug()) | 1053 | if (r45k_bvahwbug()) |
1044 | build_tlb_probe_entry(p); | 1054 | build_tlb_probe_entry(p); |
1045 | build_convert_pte_to_entrylo(p, tmp); | 1055 | build_convert_pte_to_entrylo(p, tmp); |
@@ -1421,6 +1431,108 @@ static void build_r4000_tlb_refill_handler(void) | |||
1421 | dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); | 1431 | dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); |
1422 | } | 1432 | } |
1423 | 1433 | ||
1434 | static void setup_pw(void) | ||
1435 | { | ||
1436 | unsigned long pgd_i, pgd_w; | ||
1437 | #ifndef __PAGETABLE_PMD_FOLDED | ||
1438 | unsigned long pmd_i, pmd_w; | ||
1439 | #endif | ||
1440 | unsigned long pt_i, pt_w; | ||
1441 | unsigned long pte_i, pte_w; | ||
1442 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | ||
1443 | unsigned long psn; | ||
1444 | |||
1445 | psn = ilog2(_PAGE_HUGE); /* bit used to indicate huge page */ | ||
1446 | #endif | ||
1447 | pgd_i = PGDIR_SHIFT; /* 1st level PGD */ | ||
1448 | #ifndef __PAGETABLE_PMD_FOLDED | ||
1449 | pgd_w = PGDIR_SHIFT - PMD_SHIFT + PGD_ORDER; | ||
1450 | |||
1451 | pmd_i = PMD_SHIFT; /* 2nd level PMD */ | ||
1452 | pmd_w = PMD_SHIFT - PAGE_SHIFT; | ||
1453 | #else | ||
1454 | pgd_w = PGDIR_SHIFT - PAGE_SHIFT + PGD_ORDER; | ||
1455 | #endif | ||
1456 | |||
1457 | pt_i = PAGE_SHIFT; /* 3rd level PTE */ | ||
1458 | pt_w = PAGE_SHIFT - 3; | ||
1459 | |||
1460 | pte_i = ilog2(_PAGE_GLOBAL); | ||
1461 | pte_w = 0; | ||
1462 | |||
1463 | #ifndef __PAGETABLE_PMD_FOLDED | ||
1464 | write_c0_pwfield(pgd_i << 24 | pmd_i << 12 | pt_i << 6 | pte_i); | ||
1465 | write_c0_pwsize(1 << 30 | pgd_w << 24 | pmd_w << 12 | pt_w << 6 | pte_w); | ||
1466 | #else | ||
1467 | write_c0_pwfield(pgd_i << 24 | pt_i << 6 | pte_i); | ||
1468 | write_c0_pwsize(1 << 30 | pgd_w << 24 | pt_w << 6 | pte_w); | ||
1469 | #endif | ||
1470 | |||
1471 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | ||
1472 | write_c0_pwctl(1 << 6 | psn); | ||
1473 | #endif | ||
1474 | write_c0_kpgd(swapper_pg_dir); | ||
1475 | kscratch_used_mask |= (1 << 7); /* KScratch6 is used for KPGD */ | ||
1476 | } | ||
1477 | |||
1478 | static void build_loongson3_tlb_refill_handler(void) | ||
1479 | { | ||
1480 | u32 *p = tlb_handler; | ||
1481 | struct uasm_label *l = labels; | ||
1482 | struct uasm_reloc *r = relocs; | ||
1483 | |||
1484 | memset(labels, 0, sizeof(labels)); | ||
1485 | memset(relocs, 0, sizeof(relocs)); | ||
1486 | memset(tlb_handler, 0, sizeof(tlb_handler)); | ||
1487 | |||
1488 | if (check_for_high_segbits) { | ||
1489 | uasm_i_dmfc0(&p, K0, C0_BADVADDR); | ||
1490 | uasm_i_dsrl_safe(&p, K1, K0, PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3); | ||
1491 | uasm_il_beqz(&p, &r, K1, label_vmalloc); | ||
1492 | uasm_i_nop(&p); | ||
1493 | |||
1494 | uasm_il_bgez(&p, &r, K0, label_large_segbits_fault); | ||
1495 | uasm_i_nop(&p); | ||
1496 | uasm_l_vmalloc(&l, p); | ||
1497 | } | ||
1498 | |||
1499 | uasm_i_dmfc0(&p, K1, C0_PGD); | ||
1500 | |||
1501 | uasm_i_lddir(&p, K0, K1, 3); /* global page dir */ | ||
1502 | #ifndef __PAGETABLE_PMD_FOLDED | ||
1503 | uasm_i_lddir(&p, K1, K0, 1); /* middle page dir */ | ||
1504 | #endif | ||
1505 | uasm_i_ldpte(&p, K1, 0); /* even */ | ||
1506 | uasm_i_ldpte(&p, K1, 1); /* odd */ | ||
1507 | uasm_i_tlbwr(&p); | ||
1508 | |||
1509 | /* restore page mask */ | ||
1510 | if (PM_DEFAULT_MASK >> 16) { | ||
1511 | uasm_i_lui(&p, K0, PM_DEFAULT_MASK >> 16); | ||
1512 | uasm_i_ori(&p, K0, K0, PM_DEFAULT_MASK & 0xffff); | ||
1513 | uasm_i_mtc0(&p, K0, C0_PAGEMASK); | ||
1514 | } else if (PM_DEFAULT_MASK) { | ||
1515 | uasm_i_ori(&p, K0, 0, PM_DEFAULT_MASK); | ||
1516 | uasm_i_mtc0(&p, K0, C0_PAGEMASK); | ||
1517 | } else { | ||
1518 | uasm_i_mtc0(&p, 0, C0_PAGEMASK); | ||
1519 | } | ||
1520 | |||
1521 | uasm_i_eret(&p); | ||
1522 | |||
1523 | if (check_for_high_segbits) { | ||
1524 | uasm_l_large_segbits_fault(&l, p); | ||
1525 | UASM_i_LA(&p, K1, (unsigned long)tlb_do_page_fault_0); | ||
1526 | uasm_i_jr(&p, K1); | ||
1527 | uasm_i_nop(&p); | ||
1528 | } | ||
1529 | |||
1530 | uasm_resolve_relocs(relocs, labels); | ||
1531 | memcpy((void *)(ebase + 0x80), tlb_handler, 0x80); | ||
1532 | local_flush_icache_range(ebase + 0x80, ebase + 0x100); | ||
1533 | dump_handler("loongson3_tlb_refill", (u32 *)(ebase + 0x80), 32); | ||
1534 | } | ||
1535 | |||
1424 | extern u32 handle_tlbl[], handle_tlbl_end[]; | 1536 | extern u32 handle_tlbl[], handle_tlbl_end[]; |
1425 | extern u32 handle_tlbs[], handle_tlbs_end[]; | 1537 | extern u32 handle_tlbs[], handle_tlbs_end[]; |
1426 | extern u32 handle_tlbm[], handle_tlbm_end[]; | 1538 | extern u32 handle_tlbm[], handle_tlbm_end[]; |
@@ -1468,7 +1580,10 @@ static void build_setup_pgd(void) | |||
1468 | } else { | 1580 | } else { |
1469 | /* PGD in c0_KScratch */ | 1581 | /* PGD in c0_KScratch */ |
1470 | uasm_i_jr(&p, 31); | 1582 | uasm_i_jr(&p, 31); |
1471 | UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg); | 1583 | if (cpu_has_ldpte) |
1584 | UASM_i_MTC0(&p, a0, C0_PWBASE); | ||
1585 | else | ||
1586 | UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg); | ||
1472 | } | 1587 | } |
1473 | #else | 1588 | #else |
1474 | #ifdef CONFIG_SMP | 1589 | #ifdef CONFIG_SMP |
@@ -1523,19 +1638,19 @@ iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) | |||
1523 | 1638 | ||
1524 | static void | 1639 | static void |
1525 | iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | 1640 | iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, |
1526 | unsigned int mode) | 1641 | unsigned int mode, unsigned int scratch) |
1527 | { | 1642 | { |
1528 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | ||
1529 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); | 1643 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); |
1644 | unsigned int swmode = mode & ~hwmode; | ||
1530 | 1645 | ||
1531 | if (!cpu_has_64bits) { | 1646 | if (config_enabled(CONFIG_XPA) && !cpu_has_64bits) { |
1532 | const int scratch = 1; /* Our extra working register */ | 1647 | uasm_i_lui(p, scratch, swmode >> 16); |
1533 | |||
1534 | uasm_i_lui(p, scratch, (mode >> 16)); | ||
1535 | uasm_i_or(p, pte, pte, scratch); | 1648 | uasm_i_or(p, pte, pte, scratch); |
1536 | } else | 1649 | BUG_ON(swmode & 0xffff); |
1537 | #endif | 1650 | } else { |
1538 | uasm_i_ori(p, pte, pte, mode); | 1651 | uasm_i_ori(p, pte, pte, mode); |
1652 | } | ||
1653 | |||
1539 | #ifdef CONFIG_SMP | 1654 | #ifdef CONFIG_SMP |
1540 | # ifdef CONFIG_PHYS_ADDR_T_64BIT | 1655 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
1541 | if (cpu_has_64bits) | 1656 | if (cpu_has_64bits) |
@@ -1554,6 +1669,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | |||
1554 | /* no uasm_i_nop needed */ | 1669 | /* no uasm_i_nop needed */ |
1555 | uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); | 1670 | uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); |
1556 | uasm_i_ori(p, pte, pte, hwmode); | 1671 | uasm_i_ori(p, pte, pte, hwmode); |
1672 | BUG_ON(hwmode & ~0xffff); | ||
1557 | uasm_i_sc(p, pte, sizeof(pte_t) / 2, ptr); | 1673 | uasm_i_sc(p, pte, sizeof(pte_t) / 2, ptr); |
1558 | uasm_il_beqz(p, r, pte, label_smp_pgtable_change); | 1674 | uasm_il_beqz(p, r, pte, label_smp_pgtable_change); |
1559 | /* no uasm_i_nop needed */ | 1675 | /* no uasm_i_nop needed */ |
@@ -1575,6 +1691,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | |||
1575 | if (!cpu_has_64bits) { | 1691 | if (!cpu_has_64bits) { |
1576 | uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); | 1692 | uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); |
1577 | uasm_i_ori(p, pte, pte, hwmode); | 1693 | uasm_i_ori(p, pte, pte, hwmode); |
1694 | BUG_ON(hwmode & ~0xffff); | ||
1578 | uasm_i_sw(p, pte, sizeof(pte_t) / 2, ptr); | 1695 | uasm_i_sw(p, pte, sizeof(pte_t) / 2, ptr); |
1579 | uasm_i_lw(p, pte, 0, ptr); | 1696 | uasm_i_lw(p, pte, 0, ptr); |
1580 | } | 1697 | } |
@@ -1615,9 +1732,8 @@ build_pte_present(u32 **p, struct uasm_reloc **r, | |||
1615 | cur = t; | 1732 | cur = t; |
1616 | } | 1733 | } |
1617 | uasm_i_andi(p, t, cur, | 1734 | uasm_i_andi(p, t, cur, |
1618 | (_PAGE_PRESENT | _PAGE_READ) >> _PAGE_PRESENT_SHIFT); | 1735 | (_PAGE_PRESENT | _PAGE_NO_READ) >> _PAGE_PRESENT_SHIFT); |
1619 | uasm_i_xori(p, t, t, | 1736 | uasm_i_xori(p, t, t, _PAGE_PRESENT >> _PAGE_PRESENT_SHIFT); |
1620 | (_PAGE_PRESENT | _PAGE_READ) >> _PAGE_PRESENT_SHIFT); | ||
1621 | uasm_il_bnez(p, r, t, lid); | 1737 | uasm_il_bnez(p, r, t, lid); |
1622 | if (pte == t) | 1738 | if (pte == t) |
1623 | /* You lose the SMP race :-(*/ | 1739 | /* You lose the SMP race :-(*/ |
@@ -1628,11 +1744,11 @@ build_pte_present(u32 **p, struct uasm_reloc **r, | |||
1628 | /* Make PTE valid, store result in PTR. */ | 1744 | /* Make PTE valid, store result in PTR. */ |
1629 | static void | 1745 | static void |
1630 | build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte, | 1746 | build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte, |
1631 | unsigned int ptr) | 1747 | unsigned int ptr, unsigned int scratch) |
1632 | { | 1748 | { |
1633 | unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED; | 1749 | unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED; |
1634 | 1750 | ||
1635 | iPTE_SW(p, r, pte, ptr, mode); | 1751 | iPTE_SW(p, r, pte, ptr, mode, scratch); |
1636 | } | 1752 | } |
1637 | 1753 | ||
1638 | /* | 1754 | /* |
@@ -1668,12 +1784,12 @@ build_pte_writable(u32 **p, struct uasm_reloc **r, | |||
1668 | */ | 1784 | */ |
1669 | static void | 1785 | static void |
1670 | build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte, | 1786 | build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte, |
1671 | unsigned int ptr) | 1787 | unsigned int ptr, unsigned int scratch) |
1672 | { | 1788 | { |
1673 | unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | 1789 | unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID |
1674 | | _PAGE_DIRTY); | 1790 | | _PAGE_DIRTY); |
1675 | 1791 | ||
1676 | iPTE_SW(p, r, pte, ptr, mode); | 1792 | iPTE_SW(p, r, pte, ptr, mode, scratch); |
1677 | } | 1793 | } |
1678 | 1794 | ||
1679 | /* | 1795 | /* |
@@ -1778,7 +1894,7 @@ static void build_r3000_tlb_load_handler(void) | |||
1778 | build_r3000_tlbchange_handler_head(&p, K0, K1); | 1894 | build_r3000_tlbchange_handler_head(&p, K0, K1); |
1779 | build_pte_present(&p, &r, K0, K1, -1, label_nopage_tlbl); | 1895 | build_pte_present(&p, &r, K0, K1, -1, label_nopage_tlbl); |
1780 | uasm_i_nop(&p); /* load delay */ | 1896 | uasm_i_nop(&p); /* load delay */ |
1781 | build_make_valid(&p, &r, K0, K1); | 1897 | build_make_valid(&p, &r, K0, K1, -1); |
1782 | build_r3000_tlb_reload_write(&p, &l, &r, K0, K1); | 1898 | build_r3000_tlb_reload_write(&p, &l, &r, K0, K1); |
1783 | 1899 | ||
1784 | uasm_l_nopage_tlbl(&l, p); | 1900 | uasm_l_nopage_tlbl(&l, p); |
@@ -1809,7 +1925,7 @@ static void build_r3000_tlb_store_handler(void) | |||
1809 | build_r3000_tlbchange_handler_head(&p, K0, K1); | 1925 | build_r3000_tlbchange_handler_head(&p, K0, K1); |
1810 | build_pte_writable(&p, &r, K0, K1, -1, label_nopage_tlbs); | 1926 | build_pte_writable(&p, &r, K0, K1, -1, label_nopage_tlbs); |
1811 | uasm_i_nop(&p); /* load delay */ | 1927 | uasm_i_nop(&p); /* load delay */ |
1812 | build_make_write(&p, &r, K0, K1); | 1928 | build_make_write(&p, &r, K0, K1, -1); |
1813 | build_r3000_tlb_reload_write(&p, &l, &r, K0, K1); | 1929 | build_r3000_tlb_reload_write(&p, &l, &r, K0, K1); |
1814 | 1930 | ||
1815 | uasm_l_nopage_tlbs(&l, p); | 1931 | uasm_l_nopage_tlbs(&l, p); |
@@ -1840,7 +1956,7 @@ static void build_r3000_tlb_modify_handler(void) | |||
1840 | build_r3000_tlbchange_handler_head(&p, K0, K1); | 1956 | build_r3000_tlbchange_handler_head(&p, K0, K1); |
1841 | build_pte_modifiable(&p, &r, K0, K1, -1, label_nopage_tlbm); | 1957 | build_pte_modifiable(&p, &r, K0, K1, -1, label_nopage_tlbm); |
1842 | uasm_i_nop(&p); /* load delay */ | 1958 | uasm_i_nop(&p); /* load delay */ |
1843 | build_make_write(&p, &r, K0, K1); | 1959 | build_make_write(&p, &r, K0, K1, -1); |
1844 | build_r3000_pte_reload_tlbwi(&p, K0, K1); | 1960 | build_r3000_pte_reload_tlbwi(&p, K0, K1); |
1845 | 1961 | ||
1846 | uasm_l_nopage_tlbm(&l, p); | 1962 | uasm_l_nopage_tlbm(&l, p); |
@@ -2008,7 +2124,7 @@ static void build_r4000_tlb_load_handler(void) | |||
2008 | } | 2124 | } |
2009 | uasm_l_tlbl_goaround1(&l, p); | 2125 | uasm_l_tlbl_goaround1(&l, p); |
2010 | } | 2126 | } |
2011 | build_make_valid(&p, &r, wr.r1, wr.r2); | 2127 | build_make_valid(&p, &r, wr.r1, wr.r2, wr.r3); |
2012 | build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); | 2128 | build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); |
2013 | 2129 | ||
2014 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 2130 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
@@ -2122,7 +2238,7 @@ static void build_r4000_tlb_store_handler(void) | |||
2122 | build_pte_writable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbs); | 2238 | build_pte_writable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbs); |
2123 | if (m4kc_tlbp_war()) | 2239 | if (m4kc_tlbp_war()) |
2124 | build_tlb_probe_entry(&p); | 2240 | build_tlb_probe_entry(&p); |
2125 | build_make_write(&p, &r, wr.r1, wr.r2); | 2241 | build_make_write(&p, &r, wr.r1, wr.r2, wr.r3); |
2126 | build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); | 2242 | build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); |
2127 | 2243 | ||
2128 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 2244 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
@@ -2178,7 +2294,7 @@ static void build_r4000_tlb_modify_handler(void) | |||
2178 | if (m4kc_tlbp_war()) | 2294 | if (m4kc_tlbp_war()) |
2179 | build_tlb_probe_entry(&p); | 2295 | build_tlb_probe_entry(&p); |
2180 | /* Present and writable bits set, set accessed and dirty bits. */ | 2296 | /* Present and writable bits set, set accessed and dirty bits. */ |
2181 | build_make_write(&p, &r, wr.r1, wr.r2); | 2297 | build_make_write(&p, &r, wr.r1, wr.r2, wr.r3); |
2182 | build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); | 2298 | build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); |
2183 | 2299 | ||
2184 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 2300 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
@@ -2311,9 +2427,7 @@ static void config_htw_params(void) | |||
2311 | if (CONFIG_PGTABLE_LEVELS >= 3) | 2427 | if (CONFIG_PGTABLE_LEVELS >= 3) |
2312 | pwsize |= ilog2(PTRS_PER_PMD) << MIPS_PWSIZE_MDW_SHIFT; | 2428 | pwsize |= ilog2(PTRS_PER_PMD) << MIPS_PWSIZE_MDW_SHIFT; |
2313 | 2429 | ||
2314 | /* If XPA has been enabled, PTEs are 64-bit in size. */ | 2430 | pwsize |= ilog2(sizeof(pte_t)/4) << MIPS_PWSIZE_PTEW_SHIFT; |
2315 | if (config_enabled(CONFIG_64BITS) || (read_c0_pagegrain() & PG_ELPA)) | ||
2316 | pwsize |= 1; | ||
2317 | 2431 | ||
2318 | write_c0_pwsize(pwsize); | 2432 | write_c0_pwsize(pwsize); |
2319 | 2433 | ||
@@ -2394,6 +2508,9 @@ void build_tlb_refill_handler(void) | |||
2394 | */ | 2508 | */ |
2395 | static int run_once = 0; | 2509 | static int run_once = 0; |
2396 | 2510 | ||
2511 | if (config_enabled(CONFIG_XPA) && !cpu_has_rixi) | ||
2512 | panic("Kernels supporting XPA currently require CPUs with RIXI"); | ||
2513 | |||
2397 | output_pgtable_bits_defines(); | 2514 | output_pgtable_bits_defines(); |
2398 | check_pabits(); | 2515 | check_pabits(); |
2399 | 2516 | ||
@@ -2437,13 +2554,18 @@ void build_tlb_refill_handler(void) | |||
2437 | break; | 2554 | break; |
2438 | 2555 | ||
2439 | default: | 2556 | default: |
2557 | if (cpu_has_ldpte) | ||
2558 | setup_pw(); | ||
2559 | |||
2440 | if (!run_once) { | 2560 | if (!run_once) { |
2441 | scratch_reg = allocate_kscratch(); | 2561 | scratch_reg = allocate_kscratch(); |
2442 | build_setup_pgd(); | 2562 | build_setup_pgd(); |
2443 | build_r4000_tlb_load_handler(); | 2563 | build_r4000_tlb_load_handler(); |
2444 | build_r4000_tlb_store_handler(); | 2564 | build_r4000_tlb_store_handler(); |
2445 | build_r4000_tlb_modify_handler(); | 2565 | build_r4000_tlb_modify_handler(); |
2446 | if (!cpu_has_local_ebase) | 2566 | if (cpu_has_ldpte) |
2567 | build_loongson3_tlb_refill_handler(); | ||
2568 | else if (!cpu_has_local_ebase) | ||
2447 | build_r4000_tlb_refill_handler(); | 2569 | build_r4000_tlb_refill_handler(); |
2448 | flush_tlb_handlers(); | 2570 | flush_tlb_handlers(); |
2449 | run_once++; | 2571 | run_once++; |
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c index b4a837893562..9c2220a45189 100644 --- a/arch/mips/mm/uasm-mips.c +++ b/arch/mips/mm/uasm-mips.c | |||
@@ -153,6 +153,8 @@ static struct insn insn_table[] = { | |||
153 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 153 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
154 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, | 154 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, |
155 | { insn_yield, M(spec3_op, 0, 0, 0, 0, yield_op), RS | RD }, | 155 | { insn_yield, M(spec3_op, 0, 0, 0, 0, yield_op), RS | RD }, |
156 | { insn_ldpte, M(lwc2_op, 0, 0, 0, ldpte_op, mult_op), RS | RD }, | ||
157 | { insn_lddir, M(lwc2_op, 0, 0, 0, lddir_op, mult_op), RS | RT | RD }, | ||
156 | { insn_invalid, 0, 0 } | 158 | { insn_invalid, 0, 0 } |
157 | }; | 159 | }; |
158 | 160 | ||
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 319051c34343..ad718debc35a 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
@@ -60,6 +60,7 @@ enum opcode { | |||
60 | insn_sltiu, insn_sltu, insn_sra, insn_srl, insn_srlv, insn_subu, | 60 | insn_sltiu, insn_sltu, insn_sra, insn_srl, insn_srlv, insn_subu, |
61 | insn_sw, insn_sync, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, | 61 | insn_sw, insn_sync, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, |
62 | insn_tlbwr, insn_wait, insn_wsbh, insn_xor, insn_xori, insn_yield, | 62 | insn_tlbwr, insn_wait, insn_wsbh, insn_xor, insn_xori, insn_yield, |
63 | insn_lddir, insn_ldpte, | ||
63 | }; | 64 | }; |
64 | 65 | ||
65 | struct insn { | 66 | struct insn { |
@@ -335,6 +336,8 @@ I_u1u2s3(_bbit0); | |||
335 | I_u1u2s3(_bbit1); | 336 | I_u1u2s3(_bbit1); |
336 | I_u3u1u2(_lwx) | 337 | I_u3u1u2(_lwx) |
337 | I_u3u1u2(_ldx) | 338 | I_u3u1u2(_ldx) |
339 | I_u1u2(_ldpte) | ||
340 | I_u2u1u3(_lddir) | ||
338 | 341 | ||
339 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | 342 | #ifdef CONFIG_CPU_CAVIUM_OCTEON |
340 | #include <asm/octeon/octeon.h> | 343 | #include <asm/octeon/octeon.h> |
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index 4740c82fb97a..33d5ff5069e5 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c | |||
@@ -248,10 +248,15 @@ static void __init bonito_quirks_setup(void) | |||
248 | #endif | 248 | #endif |
249 | } | 249 | } |
250 | 250 | ||
251 | void __init *plat_get_fdt(void) | ||
252 | { | ||
253 | return (void *)__dtb_start; | ||
254 | } | ||
255 | |||
251 | void __init plat_mem_setup(void) | 256 | void __init plat_mem_setup(void) |
252 | { | 257 | { |
253 | unsigned int i; | 258 | unsigned int i; |
254 | void *fdt = __dtb_start; | 259 | void *fdt = plat_get_fdt(); |
255 | 260 | ||
256 | fdt = malta_dt_shim(fdt); | 261 | fdt = malta_dt_shim(fdt); |
257 | __dt_setup_arch(fdt); | 262 | __dt_setup_arch(fdt); |
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index b7bf721eabf5..7407da04f8d6 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/i8253.h> | 21 | #include <linux/i8253.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/kernel_stat.h> | 23 | #include <linux/kernel_stat.h> |
24 | #include <linux/math64.h> | ||
24 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
25 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
@@ -72,6 +73,8 @@ static void __init estimate_frequencies(void) | |||
72 | { | 73 | { |
73 | unsigned long flags; | 74 | unsigned long flags; |
74 | unsigned int count, start; | 75 | unsigned int count, start; |
76 | unsigned char secs1, secs2, ctrl; | ||
77 | int secs; | ||
75 | cycle_t giccount = 0, gicstart = 0; | 78 | cycle_t giccount = 0, gicstart = 0; |
76 | 79 | ||
77 | #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ | 80 | #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ |
@@ -81,32 +84,51 @@ static void __init estimate_frequencies(void) | |||
81 | 84 | ||
82 | local_irq_save(flags); | 85 | local_irq_save(flags); |
83 | 86 | ||
84 | /* Start counter exactly on falling edge of update flag. */ | 87 | if (gic_present) |
88 | gic_start_count(); | ||
89 | |||
90 | /* | ||
91 | * Read counters exactly on rising edge of update flag. | ||
92 | * This helps get an accurate reading under virtualisation. | ||
93 | */ | ||
85 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | 94 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); |
86 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 95 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); |
87 | |||
88 | /* Initialize counters. */ | ||
89 | start = read_c0_count(); | 96 | start = read_c0_count(); |
90 | if (gic_present) { | 97 | if (gic_present) |
91 | gic_start_count(); | ||
92 | gicstart = gic_read_count(); | 98 | gicstart = gic_read_count(); |
93 | } | ||
94 | 99 | ||
95 | /* Read counter exactly on falling edge of update flag. */ | 100 | /* Wait for falling edge before reading RTC. */ |
96 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | 101 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); |
97 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 102 | secs1 = CMOS_READ(RTC_SECONDS); |
98 | 103 | ||
104 | /* Read counters again exactly on rising edge of update flag. */ | ||
105 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
99 | count = read_c0_count(); | 106 | count = read_c0_count(); |
100 | if (gic_present) | 107 | if (gic_present) |
101 | giccount = gic_read_count(); | 108 | giccount = gic_read_count(); |
102 | 109 | ||
110 | /* Wait for falling edge before reading RTC again. */ | ||
111 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
112 | secs2 = CMOS_READ(RTC_SECONDS); | ||
113 | |||
114 | ctrl = CMOS_READ(RTC_CONTROL); | ||
115 | |||
103 | local_irq_restore(flags); | 116 | local_irq_restore(flags); |
104 | 117 | ||
118 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
119 | secs1 = bcd2bin(secs1); | ||
120 | secs2 = bcd2bin(secs2); | ||
121 | } | ||
122 | secs = secs2 - secs1; | ||
123 | if (secs < 1) | ||
124 | secs += 60; | ||
125 | |||
105 | count -= start; | 126 | count -= start; |
127 | count /= secs; | ||
106 | mips_hpt_frequency = count; | 128 | mips_hpt_frequency = count; |
107 | 129 | ||
108 | if (gic_present) { | 130 | if (gic_present) { |
109 | giccount -= gicstart; | 131 | giccount = div_u64(giccount - gicstart, secs); |
110 | gic_frequency = giccount; | 132 | gic_frequency = giccount; |
111 | } | 133 | } |
112 | } | 134 | } |
diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c index e43f4801a245..9f2f9b2b23ce 100644 --- a/arch/mips/mti-sead3/sead3-setup.c +++ b/arch/mips/mti-sead3/sead3-setup.c | |||
@@ -83,6 +83,11 @@ static void __init parse_memsize_param(void) | |||
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | void __init *plat_get_fdt(void) | ||
87 | { | ||
88 | return (void *)__dtb_start; | ||
89 | } | ||
90 | |||
86 | void __init plat_mem_setup(void) | 91 | void __init plat_mem_setup(void) |
87 | { | 92 | { |
88 | /* allow command line/bootloader env to override memory size in DT */ | 93 | /* allow command line/bootloader env to override memory size in DT */ |
diff --git a/arch/mips/netlogic/common/reset.S b/arch/mips/netlogic/common/reset.S index edbab9b8691f..c474981a6c0d 100644 --- a/arch/mips/netlogic/common/reset.S +++ b/arch/mips/netlogic/common/reset.S | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <asm/netlogic/xlp-hal/sys.h> | 50 | #include <asm/netlogic/xlp-hal/sys.h> |
51 | #include <asm/netlogic/xlp-hal/cpucontrol.h> | 51 | #include <asm/netlogic/xlp-hal/cpucontrol.h> |
52 | 52 | ||
53 | #define CP0_EBASE $15 | ||
54 | #define SYS_CPU_COHERENT_BASE CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \ | 53 | #define SYS_CPU_COHERENT_BASE CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \ |
55 | XLP_IO_SYS_OFFSET(0) + XLP_IO_PCI_HDRSZ + \ | 54 | XLP_IO_SYS_OFFSET(0) + XLP_IO_PCI_HDRSZ + \ |
56 | SYS_CPU_NONCOHERENT_MODE * 4 | 55 | SYS_CPU_NONCOHERENT_MODE * 4 |
@@ -92,7 +91,7 @@ | |||
92 | * registers. On XLPII CPUs, usual cache instructions work. | 91 | * registers. On XLPII CPUs, usual cache instructions work. |
93 | */ | 92 | */ |
94 | .macro xlp_flush_l1_dcache | 93 | .macro xlp_flush_l1_dcache |
95 | mfc0 t0, CP0_EBASE, 0 | 94 | mfc0 t0, CP0_PRID |
96 | andi t0, t0, PRID_IMP_MASK | 95 | andi t0, t0, PRID_IMP_MASK |
97 | slt t1, t0, 0x1200 | 96 | slt t1, t0, 0x1200 |
98 | beqz t1, 15f | 97 | beqz t1, 15f |
@@ -171,7 +170,7 @@ FEXPORT(nlm_reset_entry) | |||
171 | nop | 170 | nop |
172 | 171 | ||
173 | 1: /* Entry point on core wakeup */ | 172 | 1: /* Entry point on core wakeup */ |
174 | mfc0 t0, CP0_EBASE, 0 /* processor ID */ | 173 | mfc0 t0, CP0_PRID /* processor ID */ |
175 | andi t0, PRID_IMP_MASK | 174 | andi t0, PRID_IMP_MASK |
176 | li t1, 0x1500 /* XLP 9xx */ | 175 | li t1, 0x1500 /* XLP 9xx */ |
177 | beq t0, t1, 2f /* does not need to set coherent */ | 176 | beq t0, t1, 2f /* does not need to set coherent */ |
@@ -182,8 +181,8 @@ FEXPORT(nlm_reset_entry) | |||
182 | nop | 181 | nop |
183 | 182 | ||
184 | /* set bit in SYS coherent register for the core */ | 183 | /* set bit in SYS coherent register for the core */ |
185 | mfc0 t0, CP0_EBASE, 1 | 184 | mfc0 t0, CP0_EBASE |
186 | mfc0 t1, CP0_EBASE, 1 | 185 | mfc0 t1, CP0_EBASE |
187 | srl t1, 5 | 186 | srl t1, 5 |
188 | andi t1, 0x3 /* t1 <- node */ | 187 | andi t1, 0x3 /* t1 <- node */ |
189 | li t2, 0x40000 | 188 | li t2, 0x40000 |
@@ -232,7 +231,7 @@ EXPORT(nlm_boot_siblings) | |||
232 | 231 | ||
233 | * NOTE: All GPR contents are lost after the mtcr above! | 232 | * NOTE: All GPR contents are lost after the mtcr above! |
234 | */ | 233 | */ |
235 | mfc0 v0, CP0_EBASE, 1 | 234 | mfc0 v0, CP0_EBASE |
236 | andi v0, 0x3ff /* v0 <- node/core */ | 235 | andi v0, 0x3ff /* v0 <- node/core */ |
237 | 236 | ||
238 | /* | 237 | /* |
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S index 805355b0bd05..f0cc4c9de2bb 100644 --- a/arch/mips/netlogic/common/smpboot.S +++ b/arch/mips/netlogic/common/smpboot.S | |||
@@ -48,8 +48,6 @@ | |||
48 | #include <asm/netlogic/xlp-hal/sys.h> | 48 | #include <asm/netlogic/xlp-hal/sys.h> |
49 | #include <asm/netlogic/xlp-hal/cpucontrol.h> | 49 | #include <asm/netlogic/xlp-hal/cpucontrol.h> |
50 | 50 | ||
51 | #define CP0_EBASE $15 | ||
52 | |||
53 | .set noreorder | 51 | .set noreorder |
54 | .set noat | 52 | .set noat |
55 | .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ | 53 | .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ |
@@ -86,7 +84,7 @@ NESTED(nlm_boot_secondary_cpus, 16, sp) | |||
86 | PTR_L gp, 0(t1) | 84 | PTR_L gp, 0(t1) |
87 | 85 | ||
88 | /* a0 has the processor id */ | 86 | /* a0 has the processor id */ |
89 | mfc0 a0, CP0_EBASE, 1 | 87 | mfc0 a0, CP0_EBASE |
90 | andi a0, 0x3ff /* a0 <- node/core */ | 88 | andi a0, 0x3ff /* a0 <- node/core */ |
91 | PTR_LA t0, nlm_early_init_secondary | 89 | PTR_LA t0, nlm_early_init_secondary |
92 | jalr t0 | 90 | jalr t0 |
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index 80ec929747c3..25ee69489e5e 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c | |||
@@ -58,7 +58,7 @@ void nlm_node_init(int node) | |||
58 | nodep->coremask = 1; /* node 0, boot cpu */ | 58 | nodep->coremask = 1; /* node 0, boot cpu */ |
59 | nodep->sysbase = nlm_get_sys_regbase(node); | 59 | nodep->sysbase = nlm_get_sys_regbase(node); |
60 | nodep->picbase = nlm_get_pic_regbase(node); | 60 | nodep->picbase = nlm_get_pic_regbase(node); |
61 | nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); | 61 | nodep->ebase = read_c0_ebase() & MIPS_EBASE_BASE; |
62 | if (cpu_is_xlp9xx()) | 62 | if (cpu_is_xlp9xx()) |
63 | nodep->socbus = xlp9xx_get_socbus(node); | 63 | nodep->socbus = xlp9xx_get_socbus(node); |
64 | else | 64 | else |
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index d118b9aa7647..72ceddc9a03f 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c | |||
@@ -168,7 +168,7 @@ static void nlm_init_node(void) | |||
168 | 168 | ||
169 | nodep = nlm_current_node(); | 169 | nodep = nlm_current_node(); |
170 | nodep->picbase = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET); | 170 | nodep->picbase = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET); |
171 | nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); | 171 | nodep->ebase = read_c0_ebase() & MIPS_EBASE_BASE; |
172 | spin_lock_init(&nodep->piclock); | 172 | spin_lock_init(&nodep->piclock); |
173 | } | 173 | } |
174 | 174 | ||
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index 3c9ec3ddca84..2f33992f6dff 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
@@ -77,7 +77,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
77 | struct op_mips_model *lmodel = NULL; | 77 | struct op_mips_model *lmodel = NULL; |
78 | int res; | 78 | int res; |
79 | 79 | ||
80 | switch (current_cpu_type()) { | 80 | switch (boot_cpu_type()) { |
81 | case CPU_5KC: | 81 | case CPU_5KC: |
82 | case CPU_M14KC: | 82 | case CPU_M14KC: |
83 | case CPU_M14KEC: | 83 | case CPU_M14KEC: |
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 8f988a61b7a8..45cb27469fba 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
@@ -269,11 +269,9 @@ static int mipsxx_perfcount_handler(void) | |||
269 | return handled; | 269 | return handled; |
270 | } | 270 | } |
271 | 271 | ||
272 | #define M_CONFIG1_PC (1 << 4) | ||
273 | |||
274 | static inline int __n_counters(void) | 272 | static inline int __n_counters(void) |
275 | { | 273 | { |
276 | if (!(read_c0_config1() & M_CONFIG1_PC)) | 274 | if (!cpu_has_perf) |
277 | return 0; | 275 | return 0; |
278 | if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) | 276 | if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) |
279 | return 1; | 277 | return 1; |
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c index c2ce41ea61d7..2b5427d3f35c 100644 --- a/arch/mips/pci/fixup-lantiq.c +++ b/arch/mips/pci/fixup-lantiq.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2012 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/of_irq.h> | 9 | #include <linux/of_irq.h> |
diff --git a/arch/mips/pci/ops-lantiq.c b/arch/mips/pci/ops-lantiq.c index e5738ee26f4f..f51e10899cc2 100644 --- a/arch/mips/pci/ops-lantiq.c +++ b/arch/mips/pci/ops-lantiq.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index 28952637a862..c8994c156e2d 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c | |||
@@ -76,7 +76,7 @@ static void mod_wired_entry(int entry, unsigned long entrylo0, | |||
76 | unsigned long old_ctx; | 76 | unsigned long old_ctx; |
77 | 77 | ||
78 | /* Save old context and create impossible VPN2 value */ | 78 | /* Save old context and create impossible VPN2 value */ |
79 | old_ctx = read_c0_entryhi() & 0xff; | 79 | old_ctx = read_c0_entryhi() & MIPS_ENTRYHI_ASID; |
80 | old_pagemask = read_c0_pagemask(); | 80 | old_pagemask = read_c0_pagemask(); |
81 | write_c0_index(entry); | 81 | write_c0_index(entry); |
82 | write_c0_pagemask(pagemask); | 82 | write_c0_pagemask(pagemask); |
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c index b1e061f7fdc7..7ae89d0c7099 100644 --- a/arch/mips/pci/pci-ip32.c +++ b/arch/mips/pci/pci-ip32.c | |||
@@ -116,7 +116,6 @@ static struct pci_controller mace_pci_controller = { | |||
116 | .pci_ops = &mace_pci_ops, | 116 | .pci_ops = &mace_pci_ops, |
117 | .mem_resource = &mace_pci_mem_resource, | 117 | .mem_resource = &mace_pci_mem_resource, |
118 | .io_resource = &mace_pci_io_resource, | 118 | .io_resource = &mace_pci_io_resource, |
119 | .iommu = 0, | ||
120 | .mem_offset = MACE_PCI_MEM_OFFSET, | 119 | .mem_offset = MACE_PCI_MEM_OFFSET, |
121 | .io_offset = 0, | 120 | .io_offset = 0, |
122 | .io_map_base = CKSEG1ADDR(MACEPCI_LOW_IO), | 121 | .io_map_base = CKSEG1ADDR(MACEPCI_LOW_IO), |
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index 6a15dbd085aa..b9deab17ccf2 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
diff --git a/arch/mips/pci/pci-lantiq.h b/arch/mips/pci/pci-lantiq.h index 66bf6cd6be3c..0cc71253a497 100644 --- a/arch/mips/pci/pci-lantiq.h +++ b/arch/mips/pci/pci-lantiq.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _LTQ_PCI_H__ | 9 | #ifndef _LTQ_PCI_H__ |
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c index 1ae932c2d78b..6ce816201699 100644 --- a/arch/mips/pci/pci-mt7620.c +++ b/arch/mips/pci/pci-mt7620.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Ralink MT7620A SoC PCI support | 2 | * Ralink MT7620A SoC PCI support |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2013 Bruce Chang (Mediatek) | 4 | * Copyright (C) 2007-2013 Bruce Chang (Mediatek) |
5 | * Copyright (C) 2013-2016 John Crispin <blogic@openwrt.org> | 5 | * Copyright (C) 2013-2016 John Crispin <john@phrozen.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License version 2 as published | 8 | * under the terms of the GNU General Public License version 2 as published |
diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c index a245cad4372a..f2a1050168d9 100644 --- a/arch/mips/pci/pci-rt2880.c +++ b/arch/mips/pci/pci-rt2880.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Ralink RT288x SoC PCI register definitions | 2 | * Ralink RT288x SoC PCI register definitions |
3 | * | 3 | * |
4 | * Copyright (C) 2009 John Crispin <blogic@openwrt.org> | 4 | * Copyright (C) 2009 John Crispin <john@phrozen.org> |
5 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | 5 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> |
6 | * | 6 | * |
7 | * Parts of this file are based on Ralink's 2.6.21 BSP | 7 | * Parts of this file are based on Ralink's 2.6.21 BSP |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index b8a0bf5766f2..f1b11f0dea2d 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -83,9 +83,6 @@ static void pcibios_scanbus(struct pci_controller *hose) | |||
83 | LIST_HEAD(resources); | 83 | LIST_HEAD(resources); |
84 | struct pci_bus *bus; | 84 | struct pci_bus *bus; |
85 | 85 | ||
86 | if (!hose->iommu) | ||
87 | PCI_DMA_BUS_IS_PHYS = 1; | ||
88 | |||
89 | if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) | 86 | if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) |
90 | next_busno = (*hose->get_busno)(); | 87 | next_busno = (*hose->get_busno)(); |
91 | 88 | ||
diff --git a/arch/mips/pic32/pic32mzda/time.c b/arch/mips/pic32/pic32mzda/time.c index ca6a62bb10db..62a0a78b6c64 100644 --- a/arch/mips/pic32/pic32mzda/time.c +++ b/arch/mips/pic32/pic32mzda/time.c | |||
@@ -11,13 +11,12 @@ | |||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * for more details. | 12 | * for more details. |
13 | */ | 13 | */ |
14 | #include <linux/clk.h> | ||
15 | #include <linux/clk-provider.h> | 14 | #include <linux/clk-provider.h> |
16 | #include <linux/clocksource.h> | 15 | #include <linux/clocksource.h> |
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/irqdomain.h> | ||
18 | #include <linux/of.h> | 18 | #include <linux/of.h> |
19 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
20 | #include <linux/irqdomain.h> | ||
21 | 20 | ||
22 | #include <asm/time.h> | 21 | #include <asm/time.h> |
23 | 22 | ||
@@ -58,16 +57,12 @@ unsigned int get_c0_compare_int(void) | |||
58 | 57 | ||
59 | void __init plat_time_init(void) | 58 | void __init plat_time_init(void) |
60 | { | 59 | { |
61 | struct clk *clk; | 60 | unsigned long rate = pic32_get_pbclk(7); |
62 | 61 | ||
63 | of_clk_init(NULL); | 62 | of_clk_init(NULL); |
64 | clk = clk_get_sys("cpu_clk", NULL); | ||
65 | if (IS_ERR(clk)) | ||
66 | panic("unable to get CPU clock, err=%ld", PTR_ERR(clk)); | ||
67 | 63 | ||
68 | clk_prepare_enable(clk); | 64 | pr_info("CPU Clock: %ldMHz\n", rate / 1000000); |
69 | pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000); | 65 | mips_hpt_frequency = rate / 2; |
70 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
71 | 66 | ||
72 | clocksource_probe(); | 67 | clocksource_probe(); |
73 | } | 68 | } |
diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c index 96ba2cc9ad3e..956c92eabfab 100644 --- a/arch/mips/pistachio/init.c +++ b/arch/mips/pistachio/init.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Pistachio platform setup | 2 | * Pistachio platform setup |
3 | * | 3 | * |
4 | * Copyright (C) 2014 Google, Inc. | 4 | * Copyright (C) 2014 Google, Inc. |
5 | * Copyright (C) 2016 Imagination Technologies | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 8 | * under the terms and conditions of the GNU General Public License, |
@@ -9,6 +10,7 @@ | |||
9 | */ | 10 | */ |
10 | 11 | ||
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/io.h> | ||
12 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
13 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
14 | #include <linux/of_fdt.h> | 16 | #include <linux/of_fdt.h> |
@@ -24,9 +26,38 @@ | |||
24 | #include <asm/smp-ops.h> | 26 | #include <asm/smp-ops.h> |
25 | #include <asm/traps.h> | 27 | #include <asm/traps.h> |
26 | 28 | ||
29 | /* | ||
30 | * Core revision register decoding | ||
31 | * Bits 23 to 20: Major rev | ||
32 | * Bits 15 to 8: Minor rev | ||
33 | * Bits 7 to 0: Maintenance rev | ||
34 | */ | ||
35 | #define PISTACHIO_CORE_REV_REG 0xB81483D0 | ||
36 | #define PISTACHIO_CORE_REV_A1 0x00100006 | ||
37 | #define PISTACHIO_CORE_REV_B0 0x00100106 | ||
38 | |||
27 | const char *get_system_type(void) | 39 | const char *get_system_type(void) |
28 | { | 40 | { |
29 | return "IMG Pistachio SoC"; | 41 | u32 core_rev; |
42 | const char *sys_type; | ||
43 | |||
44 | core_rev = __raw_readl((const void *)PISTACHIO_CORE_REV_REG); | ||
45 | |||
46 | switch (core_rev) { | ||
47 | case PISTACHIO_CORE_REV_B0: | ||
48 | sys_type = "IMG Pistachio SoC (B0)"; | ||
49 | break; | ||
50 | |||
51 | case PISTACHIO_CORE_REV_A1: | ||
52 | sys_type = "IMG Pistachio SoC (A1)"; | ||
53 | break; | ||
54 | |||
55 | default: | ||
56 | sys_type = "IMG Pistachio SoC"; | ||
57 | break; | ||
58 | } | ||
59 | |||
60 | return sys_type; | ||
30 | } | 61 | } |
31 | 62 | ||
32 | static void __init plat_setup_iocoherency(void) | 63 | static void __init plat_setup_iocoherency(void) |
@@ -109,6 +140,8 @@ void __init prom_init(void) | |||
109 | mips_cm_probe(); | 140 | mips_cm_probe(); |
110 | mips_cpc_probe(); | 141 | mips_cpc_probe(); |
111 | register_cps_smp_ops(); | 142 | register_cps_smp_ops(); |
143 | |||
144 | pr_info("SoC Type: %s\n", get_system_type()); | ||
112 | } | 145 | } |
113 | 146 | ||
114 | void __init prom_free_prom_memory(void) | 147 | void __init prom_free_prom_memory(void) |
diff --git a/arch/mips/pmcs-msp71xx/msp_setup.c b/arch/mips/pmcs-msp71xx/msp_setup.c index 9d293b3e9130..a63b73610fd4 100644 --- a/arch/mips/pmcs-msp71xx/msp_setup.c +++ b/arch/mips/pmcs-msp71xx/msp_setup.c | |||
@@ -118,7 +118,7 @@ void msp_restart(char *command) | |||
118 | /* No chip-specific reset code, just jump to the ROM reset vector */ | 118 | /* No chip-specific reset code, just jump to the ROM reset vector */ |
119 | set_c0_status(ST0_BEV | ST0_ERL); | 119 | set_c0_status(ST0_BEV | ST0_ERL); |
120 | change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); | 120 | change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); |
121 | flush_cache_all(); | 121 | __flush_cache_all(); |
122 | write_c0_wired(0); | 122 | write_c0_wired(0); |
123 | 123 | ||
124 | __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); | 124 | __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); |
diff --git a/arch/mips/pnx833x/common/setup.c b/arch/mips/pnx833x/common/setup.c index 99b4d94236cc..8a7443b2535e 100644 --- a/arch/mips/pnx833x/common/setup.c +++ b/arch/mips/pnx833x/common/setup.c | |||
@@ -38,9 +38,6 @@ extern void pnx833x_machine_power_off(void); | |||
38 | 38 | ||
39 | int __init plat_mem_setup(void) | 39 | int __init plat_mem_setup(void) |
40 | { | 40 | { |
41 | /* fake pci bus to avoid bounce buffers */ | ||
42 | PCI_DMA_BUS_IS_PHYS = 1; | ||
43 | |||
44 | /* set mips clock to 320MHz */ | 41 | /* set mips clock to 320MHz */ |
45 | #if defined(CONFIG_SOC_PNX8335) | 42 | #if defined(CONFIG_SOC_PNX8335) |
46 | PNX8335_WRITEFIELD(0x17, CLOCK_PLL_CPU_CTL, FREQ); | 43 | PNX8335_WRITEFIELD(0x17, CLOCK_PLL_CPU_CTL, FREQ); |
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile index 0d1795a0321e..fe3471533820 100644 --- a/arch/mips/ralink/Makefile +++ b/arch/mips/ralink/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | # Makefile for the Ralink common stuff | 4 | # Makefile for the Ralink common stuff |
5 | # | 5 | # |
6 | # Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> | 6 | # Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> |
7 | # Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 7 | # Copyright (C) 2013 John Crispin <john@phrozen.org> |
8 | 8 | ||
9 | obj-y := prom.o of.o reset.o | 9 | obj-y := prom.o of.o reset.o |
10 | 10 | ||
diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c index 5403468394fb..e1fa5972a81d 100644 --- a/arch/mips/ralink/bootrom.c +++ b/arch/mips/ralink/bootrom.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/debugfs.h> | 9 | #include <linux/debugfs.h> |
diff --git a/arch/mips/ralink/cevt-rt3352.c b/arch/mips/ralink/cevt-rt3352.c index e46f91f971c5..3ad0b0794f7d 100644 --- a/arch/mips/ralink/cevt-rt3352.c +++ b/arch/mips/ralink/cevt-rt3352.c | |||
@@ -3,7 +3,7 @@ | |||
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) 2013 by John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2013 by John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/clockchips.h> | 9 | #include <linux/clockchips.h> |
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c index 25c4a61779f1..ebaa7cc0e995 100644 --- a/arch/mips/ralink/clk.c +++ b/arch/mips/ralink/clk.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | 6 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> |
7 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h index 8e7d8e618fb9..b8245d0940d6 100644 --- a/arch/mips/ralink/common.h +++ b/arch/mips/ralink/common.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _RALINK_COMMON_H__ | 9 | #ifndef _RALINK_COMMON_H__ |
diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c index e10d10b9e82a..765d5ba98fa2 100644 --- a/arch/mips/ralink/ill_acc.c +++ b/arch/mips/ralink/ill_acc.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c index 50d6c55ab1de..2058280450b5 100644 --- a/arch/mips/ralink/irq-gic.c +++ b/arch/mips/ralink/irq-gic.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> | 6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> |
7 | * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2015 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c index 4cf77f358395..4911c1445f1a 100644 --- a/arch/mips/ralink/irq.c +++ b/arch/mips/ralink/irq.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | 6 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> |
7 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/io.h> | 10 | #include <linux/io.h> |
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index 0d3d1a97895f..88b82fe21ae6 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 10 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
@@ -581,11 +581,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
581 | (rev & CHIP_REV_ECO_MASK)); | 581 | (rev & CHIP_REV_ECO_MASK)); |
582 | 582 | ||
583 | cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); | 583 | cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); |
584 | if (is_mt76x8()) | 584 | if (is_mt76x8()) { |
585 | dram_type = cfg0 & DRAM_TYPE_MT7628_MASK; | 585 | dram_type = cfg0 & DRAM_TYPE_MT7628_MASK; |
586 | else | 586 | } else { |
587 | dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & | 587 | dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & |
588 | SYSCFG0_DRAM_TYPE_MASK; | 588 | SYSCFG0_DRAM_TYPE_MASK; |
589 | if (dram_type == SYSCFG0_DRAM_TYPE_UNKNOWN) | ||
590 | dram_type = SYSCFG0_DRAM_TYPE_SDRAM; | ||
591 | } | ||
589 | 592 | ||
590 | soc_info->mem_base = MT7620_DRAM_BASE; | 593 | soc_info->mem_base = MT7620_DRAM_BASE; |
591 | if (is_mt76x8()) | 594 | if (is_mt76x8()) |
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c index e9b9fa3e1e51..a45bbbe97ac5 100644 --- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> | 6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> |
7 | * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2015 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index f9eda5d8f82c..0aa67a2d0ae6 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
7 | * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> | 7 | * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> |
8 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 8 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/io.h> | 11 | #include <linux/io.h> |
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c index 39a9142f71be..5a73c5e14221 100644 --- a/arch/mips/ralink/prom.c +++ b/arch/mips/ralink/prom.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | 6 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> |
7 | * Copyright (C) 2010 Joonas Lahtinen <joonas.lahtinen@gmail.com> | 7 | * Copyright (C) 2010 Joonas Lahtinen <joonas.lahtinen@gmail.com> |
8 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 8 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
diff --git a/arch/mips/ralink/reset.c b/arch/mips/ralink/reset.c index ee117c4bc4a3..64543d66e76b 100644 --- a/arch/mips/ralink/reset.c +++ b/arch/mips/ralink/reset.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> | 6 | * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> |
7 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 7 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
8 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 8 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/pm.h> | 11 | #include <linux/pm.h> |
@@ -61,7 +61,7 @@ static int ralink_reset_device(struct reset_controller_dev *rcdev, | |||
61 | return ralink_deassert_device(rcdev, id); | 61 | return ralink_deassert_device(rcdev, id); |
62 | } | 62 | } |
63 | 63 | ||
64 | static struct reset_control_ops reset_ops = { | 64 | static const struct reset_control_ops reset_ops = { |
65 | .reset = ralink_reset_device, | 65 | .reset = ralink_reset_device, |
66 | .assert = ralink_assert_device, | 66 | .assert = ralink_assert_device, |
67 | .deassert = ralink_deassert_device, | 67 | .deassert = ralink_deassert_device, |
diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c index 3c84166ebcb7..285796e6d75c 100644 --- a/arch/mips/ralink/rt288x.c +++ b/arch/mips/ralink/rt288x.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 10 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c index d7c4ba43a428..c8a28c4bf29e 100644 --- a/arch/mips/ralink/rt305x.c +++ b/arch/mips/ralink/rt305x.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 10 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index fafec947b27d..4cef9162bd9b 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 8 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
9 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 9 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 10 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
diff --git a/arch/mips/ralink/timer-gic.c b/arch/mips/ralink/timer-gic.c index 5b4f186bcf95..069771dbec42 100644 --- a/arch/mips/ralink/timer-gic.c +++ b/arch/mips/ralink/timer-gic.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> | 6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> |
7 | * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | 7 | * Copyright (C) 2015 John Crispin <john@phrozen.org> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c index 82c72a15bf75..b0343ff336c5 100644 --- a/arch/mips/ralink/timer.c +++ b/arch/mips/ralink/timer.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * under the terms of the GNU General Public License version 2 as published | 3 | * under the terms of the GNU General Public License version 2 as published |
4 | * by the Free Software Foundation. | 4 | * by the Free Software Foundation. |
5 | * | 5 | * |
6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2013 John Crispin <john@phrozen.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
@@ -180,5 +180,5 @@ static struct platform_driver rt_timer_driver = { | |||
180 | module_platform_driver(rt_timer_driver); | 180 | module_platform_driver(rt_timer_driver); |
181 | 181 | ||
182 | MODULE_DESCRIPTION("Ralink RT2880 timer"); | 182 | MODULE_DESCRIPTION("Ralink RT2880 timer"); |
183 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org"); | 183 | MODULE_AUTHOR("John Crispin <john@phrozen.org"); |
184 | MODULE_LICENSE("GPL"); | 184 | MODULE_LICENSE("GPL"); |
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index cb9a095f5c5e..707b88441567 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig | |||
@@ -143,7 +143,8 @@ config SIBYTE_CFE_CONSOLE | |||
143 | config SIBYTE_BUS_WATCHER | 143 | config SIBYTE_BUS_WATCHER |
144 | bool "Support for Bus Watcher statistics" | 144 | bool "Support for Bus Watcher statistics" |
145 | depends on SIBYTE_SB1xxx_SOC && \ | 145 | depends on SIBYTE_SB1xxx_SOC && \ |
146 | (SIBYTE_BCM112X || SIBYTE_SB1250) | 146 | (SIBYTE_BCM112X || SIBYTE_SB1250 || \ |
147 | SIBYTE_BCM1x55 || SIBYTE_BCM1x80) | ||
147 | help | 148 | help |
148 | Handle and keep statistics on the bus error interrupts (COR_ECC, | 149 | Handle and keep statistics on the bus error interrupts (COR_ECC, |
149 | BAD_ECC, IO_BUS). | 150 | BAD_ECC, IO_BUS). |
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index ee3617c0c5e2..b369509e9753 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile | |||
@@ -50,13 +50,17 @@ quiet_cmd_vdsold = VDSO $@ | |||
50 | cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \ | 50 | cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \ |
51 | -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ | 51 | -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ |
52 | 52 | ||
53 | # Strip rule for the raw .so files | ||
54 | $(obj)/%.so.raw: OBJCOPYFLAGS := -S | ||
55 | $(obj)/%.so.raw: $(obj)/%.so.dbg.raw FORCE | ||
56 | $(call if_changed,objcopy) | ||
57 | |||
53 | hostprogs-y := genvdso | 58 | hostprogs-y := genvdso |
54 | 59 | ||
55 | quiet_cmd_genvdso = GENVDSO $@ | 60 | quiet_cmd_genvdso = GENVDSO $@ |
56 | define cmd_genvdso | 61 | define cmd_genvdso |
57 | cp $< $(<:%.dbg=%) && \ | 62 | $(foreach file,$(filter %.raw,$^),cp $(file) $(file:%.raw=%) &&) \ |
58 | $(OBJCOPY) -S $< $(<:%.dbg=%) && \ | 63 | $(obj)/genvdso $(<:%.raw=%) $(<:%.dbg.raw=%) $@ $(VDSO_NAME) |
59 | $(obj)/genvdso $< $(<:%.dbg=%) $@ $(VDSO_NAME) | ||
60 | endef | 64 | endef |
61 | 65 | ||
62 | # | 66 | # |
@@ -66,7 +70,10 @@ endef | |||
66 | native-abi := $(filter -mabi=%,$(KBUILD_CFLAGS)) | 70 | native-abi := $(filter -mabi=%,$(KBUILD_CFLAGS)) |
67 | 71 | ||
68 | targets += $(obj-vdso-y) | 72 | targets += $(obj-vdso-y) |
69 | targets += vdso.lds vdso.so.dbg vdso.so vdso-image.c | 73 | targets += vdso.lds |
74 | targets += vdso.so.dbg.raw vdso.so.raw | ||
75 | targets += vdso.so.dbg vdso.so | ||
76 | targets += vdso-image.c | ||
70 | 77 | ||
71 | obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o) | 78 | obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o) |
72 | 79 | ||
@@ -75,10 +82,11 @@ $(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi) | |||
75 | 82 | ||
76 | $(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi) | 83 | $(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi) |
77 | 84 | ||
78 | $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE | 85 | $(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE |
79 | $(call if_changed,vdsold) | 86 | $(call if_changed,vdsold) |
80 | 87 | ||
81 | $(obj)/vdso-image.c: $(obj)/vdso.so.dbg $(obj)/genvdso FORCE | 88 | $(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \ |
89 | $(obj)/genvdso FORCE | ||
82 | $(call if_changed,genvdso) | 90 | $(call if_changed,genvdso) |
83 | 91 | ||
84 | obj-y += vdso-image.o | 92 | obj-y += vdso-image.o |
@@ -89,7 +97,10 @@ obj-y += vdso-image.o | |||
89 | 97 | ||
90 | # Define these outside the ifdef to ensure they are picked up by clean. | 98 | # Define these outside the ifdef to ensure they are picked up by clean. |
91 | targets += $(obj-vdso-y:%.o=%-o32.o) | 99 | targets += $(obj-vdso-y:%.o=%-o32.o) |
92 | targets += vdso-o32.lds vdso-o32.so.dbg vdso-o32.so vdso-o32-image.c | 100 | targets += vdso-o32.lds |
101 | targets += vdso-o32.so.dbg.raw vdso-o32.so.raw | ||
102 | targets += vdso-o32.so.dbg vdso-o32.so | ||
103 | targets += vdso-o32-image.c | ||
93 | 104 | ||
94 | ifdef CONFIG_MIPS32_O32 | 105 | ifdef CONFIG_MIPS32_O32 |
95 | 106 | ||
@@ -109,11 +120,12 @@ $(obj)/vdso-o32.lds: KBUILD_CPPFLAGS := -mabi=32 | |||
109 | $(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE | 120 | $(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE |
110 | $(call if_changed_dep,cpp_lds_S) | 121 | $(call if_changed_dep,cpp_lds_S) |
111 | 122 | ||
112 | $(obj)/vdso-o32.so.dbg: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE | 123 | $(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE |
113 | $(call if_changed,vdsold) | 124 | $(call if_changed,vdsold) |
114 | 125 | ||
115 | $(obj)/vdso-o32-image.c: VDSO_NAME := o32 | 126 | $(obj)/vdso-o32-image.c: VDSO_NAME := o32 |
116 | $(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg $(obj)/genvdso FORCE | 127 | $(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \ |
128 | $(obj)/genvdso FORCE | ||
117 | $(call if_changed,genvdso) | 129 | $(call if_changed,genvdso) |
118 | 130 | ||
119 | obj-y += vdso-o32-image.o | 131 | obj-y += vdso-o32-image.o |
@@ -125,7 +137,10 @@ endif | |||
125 | # | 137 | # |
126 | 138 | ||
127 | targets += $(obj-vdso-y:%.o=%-n32.o) | 139 | targets += $(obj-vdso-y:%.o=%-n32.o) |
128 | targets += vdso-n32.lds vdso-n32.so.dbg vdso-n32.so vdso-n32-image.c | 140 | targets += vdso-n32.lds |
141 | targets += vdso-n32.so.dbg.raw vdso-n32.so.raw | ||
142 | targets += vdso-n32.so.dbg vdso-n32.so | ||
143 | targets += vdso-n32-image.c | ||
129 | 144 | ||
130 | ifdef CONFIG_MIPS32_N32 | 145 | ifdef CONFIG_MIPS32_N32 |
131 | 146 | ||
@@ -145,11 +160,12 @@ $(obj)/vdso-n32.lds: KBUILD_CPPFLAGS := -mabi=n32 | |||
145 | $(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE | 160 | $(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE |
146 | $(call if_changed_dep,cpp_lds_S) | 161 | $(call if_changed_dep,cpp_lds_S) |
147 | 162 | ||
148 | $(obj)/vdso-n32.so.dbg: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE | 163 | $(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE |
149 | $(call if_changed,vdsold) | 164 | $(call if_changed,vdsold) |
150 | 165 | ||
151 | $(obj)/vdso-n32-image.c: VDSO_NAME := n32 | 166 | $(obj)/vdso-n32-image.c: VDSO_NAME := n32 |
152 | $(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg $(obj)/genvdso FORCE | 167 | $(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \ |
168 | $(obj)/genvdso FORCE | ||
153 | $(call if_changed,genvdso) | 169 | $(call if_changed,genvdso) |
154 | 170 | ||
155 | obj-y += vdso-n32-image.o | 171 | obj-y += vdso-n32-image.o |
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c index d7f755833c3f..39a0db3e2b34 100644 --- a/arch/mips/vr41xx/common/pmu.c +++ b/arch/mips/vr41xx/common/pmu.c | |||
@@ -73,7 +73,7 @@ static inline void software_reset(void) | |||
73 | default: | 73 | default: |
74 | set_c0_status(ST0_BEV | ST0_ERL); | 74 | set_c0_status(ST0_BEV | ST0_ERL); |
75 | change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); | 75 | change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); |
76 | flush_cache_all(); | 76 | __flush_cache_all(); |
77 | write_c0_wired(0); | 77 | write_c0_wired(0); |
78 | __asm__("jr %0"::"r"(0xbfc00000)); | 78 | __asm__("jr %0"::"r"(0xbfc00000)); |
79 | break; | 79 | break; |
diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index f364fa4d24eb..72fe0a5a8bf3 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c | |||
@@ -30,6 +30,10 @@ | |||
30 | #include <asm/signal.h> | 30 | #include <asm/signal.h> |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | #ifdef CONFIG_MIPS | ||
34 | #include <asm/traps.h> | ||
35 | #endif | ||
36 | |||
33 | #define ARB_ERR_CAP_CLEAR (1 << 0) | 37 | #define ARB_ERR_CAP_CLEAR (1 << 0) |
34 | #define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12) | 38 | #define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12) |
35 | #define ARB_ERR_CAP_STATUS_TEA (1 << 11) | 39 | #define ARB_ERR_CAP_STATUS_TEA (1 << 11) |
@@ -238,6 +242,29 @@ static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr, | |||
238 | } | 242 | } |
239 | #endif | 243 | #endif |
240 | 244 | ||
245 | #ifdef CONFIG_MIPS | ||
246 | static int brcmstb_bus_error_handler(struct pt_regs *regs, int is_fixup) | ||
247 | { | ||
248 | int ret = 0; | ||
249 | struct brcmstb_gisb_arb_device *gdev; | ||
250 | u32 cap_status; | ||
251 | |||
252 | list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next) { | ||
253 | cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS); | ||
254 | |||
255 | /* Invalid captured address, bail out */ | ||
256 | if (!(cap_status & ARB_ERR_CAP_STATUS_VALID)) { | ||
257 | is_fixup = 1; | ||
258 | goto out; | ||
259 | } | ||
260 | |||
261 | ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error"); | ||
262 | } | ||
263 | out: | ||
264 | return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; | ||
265 | } | ||
266 | #endif | ||
267 | |||
241 | static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id) | 268 | static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id) |
242 | { | 269 | { |
243 | brcmstb_gisb_arb_decode_addr(dev_id, "timeout"); | 270 | brcmstb_gisb_arb_decode_addr(dev_id, "timeout"); |
@@ -355,6 +382,9 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev) | |||
355 | hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, | 382 | hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, |
356 | "imprecise external abort"); | 383 | "imprecise external abort"); |
357 | #endif | 384 | #endif |
385 | #ifdef CONFIG_MIPS | ||
386 | board_be_handler = brcmstb_bus_error_handler; | ||
387 | #endif | ||
358 | 388 | ||
359 | dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n", | 389 | dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n", |
360 | gdev->base, timeout_irq, tea_irq); | 390 | gdev->base, timeout_irq, tea_irq); |
diff --git a/drivers/bus/mips_cdmm.c b/drivers/bus/mips_cdmm.c index 1c543effe062..cad49bc38b3e 100644 --- a/drivers/bus/mips_cdmm.c +++ b/drivers/bus/mips_cdmm.c | |||
@@ -599,8 +599,8 @@ BUILD_PERDEV_HELPER(cpu_up) /* int mips_cdmm_cpu_up_helper(...) */ | |||
599 | * mips_cdmm_bus_down() - Tear down the CDMM bus. | 599 | * mips_cdmm_bus_down() - Tear down the CDMM bus. |
600 | * @data: Pointer to unsigned int CPU number. | 600 | * @data: Pointer to unsigned int CPU number. |
601 | * | 601 | * |
602 | * This work_on_cpu callback function is executed on a given CPU to call the | 602 | * This function is executed on the hotplugged CPU and calls the CDMM |
603 | * CDMM driver cpu_down callback for all devices on that CPU. | 603 | * driver cpu_down callback for all devices on that CPU. |
604 | */ | 604 | */ |
605 | static long mips_cdmm_bus_down(void *data) | 605 | static long mips_cdmm_bus_down(void *data) |
606 | { | 606 | { |
@@ -630,7 +630,9 @@ static long mips_cdmm_bus_down(void *data) | |||
630 | * CDMM devices on that CPU, or to call the CDMM driver cpu_up callback for all | 630 | * CDMM devices on that CPU, or to call the CDMM driver cpu_up callback for all |
631 | * devices already discovered on that CPU. | 631 | * devices already discovered on that CPU. |
632 | * | 632 | * |
633 | * It is used during initialisation and when CPUs are brought online. | 633 | * It is used as work_on_cpu callback function during |
634 | * initialisation. When CPUs are brought online the function is | ||
635 | * invoked directly on the hotplugged CPU. | ||
634 | */ | 636 | */ |
635 | static long mips_cdmm_bus_up(void *data) | 637 | static long mips_cdmm_bus_up(void *data) |
636 | { | 638 | { |
@@ -677,10 +679,10 @@ static int mips_cdmm_cpu_notify(struct notifier_block *nb, | |||
677 | switch (action & ~CPU_TASKS_FROZEN) { | 679 | switch (action & ~CPU_TASKS_FROZEN) { |
678 | case CPU_ONLINE: | 680 | case CPU_ONLINE: |
679 | case CPU_DOWN_FAILED: | 681 | case CPU_DOWN_FAILED: |
680 | work_on_cpu(cpu, mips_cdmm_bus_up, &cpu); | 682 | mips_cdmm_bus_up(&cpu); |
681 | break; | 683 | break; |
682 | case CPU_DOWN_PREPARE: | 684 | case CPU_DOWN_PREPARE: |
683 | work_on_cpu(cpu, mips_cdmm_bus_down, &cpu); | 685 | mips_cdmm_bus_down(&cpu); |
684 | break; | 686 | break; |
685 | default: | 687 | default: |
686 | return NOTIFY_DONE; | 688 | return NOTIFY_DONE; |
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c45554957499..90518cd7fc9c 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -197,6 +197,9 @@ config COMMON_CLK_PXA | |||
197 | ---help--- | 197 | ---help--- |
198 | Support for the Marvell PXA SoC. | 198 | Support for the Marvell PXA SoC. |
199 | 199 | ||
200 | config COMMON_CLK_PIC32 | ||
201 | def_bool COMMON_CLK && MACH_PIC32 | ||
202 | |||
200 | source "drivers/clk/bcm/Kconfig" | 203 | source "drivers/clk/bcm/Kconfig" |
201 | source "drivers/clk/hisilicon/Kconfig" | 204 | source "drivers/clk/hisilicon/Kconfig" |
202 | source "drivers/clk/mvebu/Kconfig" | 205 | source "drivers/clk/mvebu/Kconfig" |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 46869d696e4d..18e64bbeeaf4 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -58,6 +58,7 @@ obj-$(CONFIG_ARCH_MXC) += imx/ | |||
58 | obj-$(CONFIG_MACH_INGENIC) += ingenic/ | 58 | obj-$(CONFIG_MACH_INGENIC) += ingenic/ |
59 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ | 59 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ |
60 | obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ | 60 | obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ |
61 | obj-$(CONFIG_MACH_PIC32) += microchip/ | ||
61 | ifeq ($(CONFIG_COMMON_CLK), y) | 62 | ifeq ($(CONFIG_COMMON_CLK), y) |
62 | obj-$(CONFIG_ARCH_MMP) += mmp/ | 63 | obj-$(CONFIG_ARCH_MMP) += mmp/ |
63 | endif | 64 | endif |
diff --git a/drivers/clk/microchip/Makefile b/drivers/clk/microchip/Makefile new file mode 100644 index 000000000000..2152f418106a --- /dev/null +++ b/drivers/clk/microchip/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-$(CONFIG_COMMON_CLK_PIC32) += clk-core.o | ||
2 | obj-$(CONFIG_PIC32MZDA) += clk-pic32mzda.o | ||
diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c new file mode 100644 index 000000000000..ca85cea17839 --- /dev/null +++ b/drivers/clk/microchip/clk-core.c | |||
@@ -0,0 +1,1031 @@ | |||
1 | /* | ||
2 | * Purna Chandra Mandal,<purna.mandal@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <linux/clk-provider.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/iopoll.h> | ||
19 | #include <asm/mach-pic32/pic32.h> | ||
20 | #include <asm/traps.h> | ||
21 | |||
22 | #include "clk-core.h" | ||
23 | |||
24 | /* OSCCON Reg fields */ | ||
25 | #define OSC_CUR_MASK 0x07 | ||
26 | #define OSC_CUR_SHIFT 12 | ||
27 | #define OSC_NEW_MASK 0x07 | ||
28 | #define OSC_NEW_SHIFT 8 | ||
29 | #define OSC_SWEN BIT(0) | ||
30 | |||
31 | /* SPLLCON Reg fields */ | ||
32 | #define PLL_RANGE_MASK 0x07 | ||
33 | #define PLL_RANGE_SHIFT 0 | ||
34 | #define PLL_ICLK_MASK 0x01 | ||
35 | #define PLL_ICLK_SHIFT 7 | ||
36 | #define PLL_IDIV_MASK 0x07 | ||
37 | #define PLL_IDIV_SHIFT 8 | ||
38 | #define PLL_ODIV_MASK 0x07 | ||
39 | #define PLL_ODIV_SHIFT 24 | ||
40 | #define PLL_MULT_MASK 0x7F | ||
41 | #define PLL_MULT_SHIFT 16 | ||
42 | #define PLL_MULT_MAX 128 | ||
43 | #define PLL_ODIV_MIN 1 | ||
44 | #define PLL_ODIV_MAX 5 | ||
45 | |||
46 | /* Peripheral Bus Clock Reg Fields */ | ||
47 | #define PB_DIV_MASK 0x7f | ||
48 | #define PB_DIV_SHIFT 0 | ||
49 | #define PB_DIV_READY BIT(11) | ||
50 | #define PB_DIV_ENABLE BIT(15) | ||
51 | #define PB_DIV_MAX 128 | ||
52 | #define PB_DIV_MIN 0 | ||
53 | |||
54 | /* Reference Oscillator Control Reg fields */ | ||
55 | #define REFO_SEL_MASK 0x0f | ||
56 | #define REFO_SEL_SHIFT 0 | ||
57 | #define REFO_ACTIVE BIT(8) | ||
58 | #define REFO_DIVSW_EN BIT(9) | ||
59 | #define REFO_OE BIT(12) | ||
60 | #define REFO_ON BIT(15) | ||
61 | #define REFO_DIV_SHIFT 16 | ||
62 | #define REFO_DIV_MASK 0x7fff | ||
63 | |||
64 | /* Reference Oscillator Trim Register Fields */ | ||
65 | #define REFO_TRIM_REG 0x10 | ||
66 | #define REFO_TRIM_MASK 0x1ff | ||
67 | #define REFO_TRIM_SHIFT 23 | ||
68 | #define REFO_TRIM_MAX 511 | ||
69 | |||
70 | /* Mux Slew Control Register fields */ | ||
71 | #define SLEW_BUSY BIT(0) | ||
72 | #define SLEW_DOWNEN BIT(1) | ||
73 | #define SLEW_UPEN BIT(2) | ||
74 | #define SLEW_DIV 0x07 | ||
75 | #define SLEW_DIV_SHIFT 8 | ||
76 | #define SLEW_SYSDIV 0x0f | ||
77 | #define SLEW_SYSDIV_SHIFT 20 | ||
78 | |||
79 | /* Clock Poll Timeout */ | ||
80 | #define LOCK_TIMEOUT_US USEC_PER_MSEC | ||
81 | |||
82 | /* SoC specific clock needed during SPLL clock rate switch */ | ||
83 | static struct clk_hw *pic32_sclk_hw; | ||
84 | |||
85 | /* add instruction pipeline delay while CPU clock is in-transition. */ | ||
86 | #define cpu_nop5() \ | ||
87 | do { \ | ||
88 | __asm__ __volatile__("nop"); \ | ||
89 | __asm__ __volatile__("nop"); \ | ||
90 | __asm__ __volatile__("nop"); \ | ||
91 | __asm__ __volatile__("nop"); \ | ||
92 | __asm__ __volatile__("nop"); \ | ||
93 | } while (0) | ||
94 | |||
95 | /* Perpheral bus clocks */ | ||
96 | struct pic32_periph_clk { | ||
97 | struct clk_hw hw; | ||
98 | void __iomem *ctrl_reg; | ||
99 | struct pic32_clk_common *core; | ||
100 | }; | ||
101 | |||
102 | #define clkhw_to_pbclk(_hw) container_of(_hw, struct pic32_periph_clk, hw) | ||
103 | |||
104 | static int pbclk_is_enabled(struct clk_hw *hw) | ||
105 | { | ||
106 | struct pic32_periph_clk *pb = clkhw_to_pbclk(hw); | ||
107 | |||
108 | return readl(pb->ctrl_reg) & PB_DIV_ENABLE; | ||
109 | } | ||
110 | |||
111 | static int pbclk_enable(struct clk_hw *hw) | ||
112 | { | ||
113 | struct pic32_periph_clk *pb = clkhw_to_pbclk(hw); | ||
114 | |||
115 | writel(PB_DIV_ENABLE, PIC32_SET(pb->ctrl_reg)); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static void pbclk_disable(struct clk_hw *hw) | ||
120 | { | ||
121 | struct pic32_periph_clk *pb = clkhw_to_pbclk(hw); | ||
122 | |||
123 | writel(PB_DIV_ENABLE, PIC32_CLR(pb->ctrl_reg)); | ||
124 | } | ||
125 | |||
126 | static unsigned long calc_best_divided_rate(unsigned long rate, | ||
127 | unsigned long parent_rate, | ||
128 | u32 divider_max, | ||
129 | u32 divider_min) | ||
130 | { | ||
131 | unsigned long divided_rate, divided_rate_down, best_rate; | ||
132 | unsigned long div, div_up; | ||
133 | |||
134 | /* eq. clk_rate = parent_rate / divider. | ||
135 | * | ||
136 | * Find best divider to produce closest of target divided rate. | ||
137 | */ | ||
138 | div = parent_rate / rate; | ||
139 | div = clamp_val(div, divider_min, divider_max); | ||
140 | div_up = clamp_val(div + 1, divider_min, divider_max); | ||
141 | |||
142 | divided_rate = parent_rate / div; | ||
143 | divided_rate_down = parent_rate / div_up; | ||
144 | if (abs(rate - divided_rate_down) < abs(rate - divided_rate)) | ||
145 | best_rate = divided_rate_down; | ||
146 | else | ||
147 | best_rate = divided_rate; | ||
148 | |||
149 | return best_rate; | ||
150 | } | ||
151 | |||
152 | static inline u32 pbclk_read_pbdiv(struct pic32_periph_clk *pb) | ||
153 | { | ||
154 | return ((readl(pb->ctrl_reg) >> PB_DIV_SHIFT) & PB_DIV_MASK) + 1; | ||
155 | } | ||
156 | |||
157 | static unsigned long pbclk_recalc_rate(struct clk_hw *hw, | ||
158 | unsigned long parent_rate) | ||
159 | { | ||
160 | struct pic32_periph_clk *pb = clkhw_to_pbclk(hw); | ||
161 | |||
162 | return parent_rate / pbclk_read_pbdiv(pb); | ||
163 | } | ||
164 | |||
165 | static long pbclk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
166 | unsigned long *parent_rate) | ||
167 | { | ||
168 | return calc_best_divided_rate(rate, *parent_rate, | ||
169 | PB_DIV_MAX, PB_DIV_MIN); | ||
170 | } | ||
171 | |||
172 | static int pbclk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
173 | unsigned long parent_rate) | ||
174 | { | ||
175 | struct pic32_periph_clk *pb = clkhw_to_pbclk(hw); | ||
176 | unsigned long flags; | ||
177 | u32 v, div; | ||
178 | int err; | ||
179 | |||
180 | /* check & wait for DIV_READY */ | ||
181 | err = readl_poll_timeout(pb->ctrl_reg, v, v & PB_DIV_READY, | ||
182 | 1, LOCK_TIMEOUT_US); | ||
183 | if (err) | ||
184 | return err; | ||
185 | |||
186 | /* calculate clkdiv and best rate */ | ||
187 | div = DIV_ROUND_CLOSEST(parent_rate, rate); | ||
188 | |||
189 | spin_lock_irqsave(&pb->core->reg_lock, flags); | ||
190 | |||
191 | /* apply new div */ | ||
192 | v = readl(pb->ctrl_reg); | ||
193 | v &= ~PB_DIV_MASK; | ||
194 | v |= (div - 1); | ||
195 | |||
196 | pic32_syskey_unlock(); | ||
197 | |||
198 | writel(v, pb->ctrl_reg); | ||
199 | |||
200 | spin_unlock_irqrestore(&pb->core->reg_lock, flags); | ||
201 | |||
202 | /* wait again, for pbdivready */ | ||
203 | err = readl_poll_timeout_atomic(pb->ctrl_reg, v, v & PB_DIV_READY, | ||
204 | 1, LOCK_TIMEOUT_US); | ||
205 | if (err) | ||
206 | return err; | ||
207 | |||
208 | /* confirm that new div is applied correctly */ | ||
209 | return (pbclk_read_pbdiv(pb) == div) ? 0 : -EBUSY; | ||
210 | } | ||
211 | |||
212 | const struct clk_ops pic32_pbclk_ops = { | ||
213 | .enable = pbclk_enable, | ||
214 | .disable = pbclk_disable, | ||
215 | .is_enabled = pbclk_is_enabled, | ||
216 | .recalc_rate = pbclk_recalc_rate, | ||
217 | .round_rate = pbclk_round_rate, | ||
218 | .set_rate = pbclk_set_rate, | ||
219 | }; | ||
220 | |||
221 | struct clk *pic32_periph_clk_register(const struct pic32_periph_clk_data *desc, | ||
222 | struct pic32_clk_common *core) | ||
223 | { | ||
224 | struct pic32_periph_clk *pbclk; | ||
225 | struct clk *clk; | ||
226 | |||
227 | pbclk = devm_kzalloc(core->dev, sizeof(*pbclk), GFP_KERNEL); | ||
228 | if (!pbclk) | ||
229 | return ERR_PTR(-ENOMEM); | ||
230 | |||
231 | pbclk->hw.init = &desc->init_data; | ||
232 | pbclk->core = core; | ||
233 | pbclk->ctrl_reg = desc->ctrl_reg + core->iobase; | ||
234 | |||
235 | clk = devm_clk_register(core->dev, &pbclk->hw); | ||
236 | if (IS_ERR(clk)) { | ||
237 | dev_err(core->dev, "%s: clk_register() failed\n", __func__); | ||
238 | devm_kfree(core->dev, pbclk); | ||
239 | } | ||
240 | |||
241 | return clk; | ||
242 | } | ||
243 | |||
244 | /* Reference oscillator operations */ | ||
245 | struct pic32_ref_osc { | ||
246 | struct clk_hw hw; | ||
247 | void __iomem *ctrl_reg; | ||
248 | const u32 *parent_map; | ||
249 | struct pic32_clk_common *core; | ||
250 | }; | ||
251 | |||
252 | #define clkhw_to_refosc(_hw) container_of(_hw, struct pic32_ref_osc, hw) | ||
253 | |||
254 | static int roclk_is_enabled(struct clk_hw *hw) | ||
255 | { | ||
256 | struct pic32_ref_osc *refo = clkhw_to_refosc(hw); | ||
257 | |||
258 | return readl(refo->ctrl_reg) & REFO_ON; | ||
259 | } | ||
260 | |||
261 | static int roclk_enable(struct clk_hw *hw) | ||
262 | { | ||
263 | struct pic32_ref_osc *refo = clkhw_to_refosc(hw); | ||
264 | |||
265 | writel(REFO_ON | REFO_OE, PIC32_SET(refo->ctrl_reg)); | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static void roclk_disable(struct clk_hw *hw) | ||
270 | { | ||
271 | struct pic32_ref_osc *refo = clkhw_to_refosc(hw); | ||
272 | |||
273 | writel(REFO_ON | REFO_OE, PIC32_CLR(refo->ctrl_reg)); | ||
274 | } | ||
275 | |||
276 | static void roclk_init(struct clk_hw *hw) | ||
277 | { | ||
278 | /* initialize clock in disabled state */ | ||
279 | roclk_disable(hw); | ||
280 | } | ||
281 | |||
282 | static u8 roclk_get_parent(struct clk_hw *hw) | ||
283 | { | ||
284 | struct pic32_ref_osc *refo = clkhw_to_refosc(hw); | ||
285 | u32 v, i; | ||
286 | |||
287 | v = (readl(refo->ctrl_reg) >> REFO_SEL_SHIFT) & REFO_SEL_MASK; | ||
288 | |||
289 | if (!refo->parent_map) | ||
290 | return v; | ||
291 | |||
292 | for (i = 0; i < clk_hw_get_num_parents(hw); i++) | ||
293 | if (refo->parent_map[i] == v) | ||
294 | return i; | ||
295 | |||
296 | return -EINVAL; | ||
297 | } | ||
298 | |||
299 | static unsigned long roclk_calc_rate(unsigned long parent_rate, | ||
300 | u32 rodiv, u32 rotrim) | ||
301 | { | ||
302 | u64 rate64; | ||
303 | |||
304 | /* fout = fin / [2 * {div + (trim / 512)}] | ||
305 | * = fin * 512 / [1024 * div + 2 * trim] | ||
306 | * = fin * 256 / (512 * div + trim) | ||
307 | * = (fin << 8) / ((div << 9) + trim) | ||
308 | */ | ||
309 | if (rotrim) { | ||
310 | rodiv = (rodiv << 9) + rotrim; | ||
311 | rate64 = parent_rate; | ||
312 | rate64 <<= 8; | ||
313 | do_div(rate64, rodiv); | ||
314 | } else if (rodiv) { | ||
315 | rate64 = parent_rate / (rodiv << 1); | ||
316 | } else { | ||
317 | rate64 = parent_rate; | ||
318 | } | ||
319 | return rate64; | ||
320 | } | ||
321 | |||
322 | static void roclk_calc_div_trim(unsigned long rate, | ||
323 | unsigned long parent_rate, | ||
324 | u32 *rodiv_p, u32 *rotrim_p) | ||
325 | { | ||
326 | u32 div, rotrim, rodiv; | ||
327 | u64 frac; | ||
328 | |||
329 | /* Find integer approximation of floating-point arithmetic. | ||
330 | * fout = fin / [2 * {rodiv + (rotrim / 512)}] ... (1) | ||
331 | * i.e. fout = fin / 2 * DIV | ||
332 | * whereas DIV = rodiv + (rotrim / 512) | ||
333 | * | ||
334 | * Since kernel does not perform floating-point arithmatic so | ||
335 | * (rotrim/512) will be zero. And DIV & rodiv will result same. | ||
336 | * | ||
337 | * ie. fout = (fin * 256) / [(512 * rodiv) + rotrim] ... from (1) | ||
338 | * ie. rotrim = ((fin * 256) / fout) - (512 * DIV) | ||
339 | */ | ||
340 | if (parent_rate <= rate) { | ||
341 | div = 0; | ||
342 | frac = 0; | ||
343 | rodiv = 0; | ||
344 | rotrim = 0; | ||
345 | } else { | ||
346 | div = parent_rate / (rate << 1); | ||
347 | frac = parent_rate; | ||
348 | frac <<= 8; | ||
349 | do_div(frac, rate); | ||
350 | frac -= (u64)(div << 9); | ||
351 | |||
352 | rodiv = (div > REFO_DIV_MASK) ? REFO_DIV_MASK : div; | ||
353 | rotrim = (frac >= REFO_TRIM_MAX) ? REFO_TRIM_MAX : frac; | ||
354 | } | ||
355 | |||
356 | if (rodiv_p) | ||
357 | *rodiv_p = rodiv; | ||
358 | |||
359 | if (rotrim_p) | ||
360 | *rotrim_p = rotrim; | ||
361 | } | ||
362 | |||
363 | static unsigned long roclk_recalc_rate(struct clk_hw *hw, | ||
364 | unsigned long parent_rate) | ||
365 | { | ||
366 | struct pic32_ref_osc *refo = clkhw_to_refosc(hw); | ||
367 | u32 v, rodiv, rotrim; | ||
368 | |||
369 | /* get rodiv */ | ||
370 | v = readl(refo->ctrl_reg); | ||
371 | rodiv = (v >> REFO_DIV_SHIFT) & REFO_DIV_MASK; | ||
372 | |||
373 | /* get trim */ | ||
374 | v = readl(refo->ctrl_reg + REFO_TRIM_REG); | ||
375 | rotrim = (v >> REFO_TRIM_SHIFT) & REFO_TRIM_MASK; | ||
376 | |||
377 | return roclk_calc_rate(parent_rate, rodiv, rotrim); | ||
378 | } | ||
379 | |||
380 | static long roclk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
381 | unsigned long *parent_rate) | ||
382 | { | ||
383 | u32 rotrim, rodiv; | ||
384 | |||
385 | /* calculate dividers for new rate */ | ||
386 | roclk_calc_div_trim(rate, *parent_rate, &rodiv, &rotrim); | ||
387 | |||
388 | /* caclulate new rate (rounding) based on new rodiv & rotrim */ | ||
389 | return roclk_calc_rate(*parent_rate, rodiv, rotrim); | ||
390 | } | ||
391 | |||
392 | static int roclk_determine_rate(struct clk_hw *hw, | ||
393 | struct clk_rate_request *req) | ||
394 | { | ||
395 | struct clk_hw *parent_clk, *best_parent_clk = NULL; | ||
396 | unsigned int i, delta, best_delta = -1; | ||
397 | unsigned long parent_rate, best_parent_rate = 0; | ||
398 | unsigned long best = 0, nearest_rate; | ||
399 | |||
400 | /* find a parent which can generate nearest clkrate >= rate */ | ||
401 | for (i = 0; i < clk_hw_get_num_parents(hw); i++) { | ||
402 | /* get parent */ | ||
403 | parent_clk = clk_hw_get_parent_by_index(hw, i); | ||
404 | if (!parent_clk) | ||
405 | continue; | ||
406 | |||
407 | /* skip if parent runs slower than target rate */ | ||
408 | parent_rate = clk_hw_get_rate(parent_clk); | ||
409 | if (req->rate > parent_rate) | ||
410 | continue; | ||
411 | |||
412 | nearest_rate = roclk_round_rate(hw, req->rate, &parent_rate); | ||
413 | delta = abs(nearest_rate - req->rate); | ||
414 | if ((nearest_rate >= req->rate) && (delta < best_delta)) { | ||
415 | best_parent_clk = parent_clk; | ||
416 | best_parent_rate = parent_rate; | ||
417 | best = nearest_rate; | ||
418 | best_delta = delta; | ||
419 | |||
420 | if (delta == 0) | ||
421 | break; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | /* if no match found, retain old rate */ | ||
426 | if (!best_parent_clk) { | ||
427 | pr_err("%s:%s, no parent found for rate %lu.\n", | ||
428 | __func__, clk_hw_get_name(hw), req->rate); | ||
429 | return clk_hw_get_rate(hw); | ||
430 | } | ||
431 | |||
432 | pr_debug("%s,rate %lu, best_parent(%s, %lu), best %lu, delta %d\n", | ||
433 | clk_hw_get_name(hw), req->rate, | ||
434 | clk_hw_get_name(best_parent_clk), best_parent_rate, | ||
435 | best, best_delta); | ||
436 | |||
437 | if (req->best_parent_rate) | ||
438 | req->best_parent_rate = best_parent_rate; | ||
439 | |||
440 | if (req->best_parent_hw) | ||
441 | req->best_parent_hw = best_parent_clk; | ||
442 | |||
443 | return best; | ||
444 | } | ||
445 | |||
446 | static int roclk_set_parent(struct clk_hw *hw, u8 index) | ||
447 | { | ||
448 | struct pic32_ref_osc *refo = clkhw_to_refosc(hw); | ||
449 | unsigned long flags; | ||
450 | u32 v; | ||
451 | int err; | ||
452 | |||
453 | if (refo->parent_map) | ||
454 | index = refo->parent_map[index]; | ||
455 | |||
456 | /* wait until ACTIVE bit is zero or timeout */ | ||
457 | err = readl_poll_timeout(refo->ctrl_reg, v, !(v & REFO_ACTIVE), | ||
458 | 1, LOCK_TIMEOUT_US); | ||
459 | if (err) { | ||
460 | pr_err("%s: poll failed, clk active\n", clk_hw_get_name(hw)); | ||
461 | return err; | ||
462 | } | ||
463 | |||
464 | spin_lock_irqsave(&refo->core->reg_lock, flags); | ||
465 | |||
466 | pic32_syskey_unlock(); | ||
467 | |||
468 | /* calculate & apply new */ | ||
469 | v = readl(refo->ctrl_reg); | ||
470 | v &= ~(REFO_SEL_MASK << REFO_SEL_SHIFT); | ||
471 | v |= index << REFO_SEL_SHIFT; | ||
472 | |||
473 | writel(v, refo->ctrl_reg); | ||
474 | |||
475 | spin_unlock_irqrestore(&refo->core->reg_lock, flags); | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static int roclk_set_rate_and_parent(struct clk_hw *hw, | ||
481 | unsigned long rate, | ||
482 | unsigned long parent_rate, | ||
483 | u8 index) | ||
484 | { | ||
485 | struct pic32_ref_osc *refo = clkhw_to_refosc(hw); | ||
486 | unsigned long flags; | ||
487 | u32 trim, rodiv, v; | ||
488 | int err; | ||
489 | |||
490 | /* calculate new rodiv & rotrim for new rate */ | ||
491 | roclk_calc_div_trim(rate, parent_rate, &rodiv, &trim); | ||
492 | |||
493 | pr_debug("parent_rate = %lu, rate = %lu, div = %d, trim = %d\n", | ||
494 | parent_rate, rate, rodiv, trim); | ||
495 | |||
496 | /* wait till source change is active */ | ||
497 | err = readl_poll_timeout(refo->ctrl_reg, v, | ||
498 | !(v & (REFO_ACTIVE | REFO_DIVSW_EN)), | ||
499 | 1, LOCK_TIMEOUT_US); | ||
500 | if (err) { | ||
501 | pr_err("%s: poll timedout, clock is still active\n", __func__); | ||
502 | return err; | ||
503 | } | ||
504 | |||
505 | spin_lock_irqsave(&refo->core->reg_lock, flags); | ||
506 | v = readl(refo->ctrl_reg); | ||
507 | |||
508 | pic32_syskey_unlock(); | ||
509 | |||
510 | /* apply parent, if required */ | ||
511 | if (refo->parent_map) | ||
512 | index = refo->parent_map[index]; | ||
513 | |||
514 | v &= ~(REFO_SEL_MASK << REFO_SEL_SHIFT); | ||
515 | v |= index << REFO_SEL_SHIFT; | ||
516 | |||
517 | /* apply RODIV */ | ||
518 | v &= ~(REFO_DIV_MASK << REFO_DIV_SHIFT); | ||
519 | v |= rodiv << REFO_DIV_SHIFT; | ||
520 | writel(v, refo->ctrl_reg); | ||
521 | |||
522 | /* apply ROTRIM */ | ||
523 | v = readl(refo->ctrl_reg + REFO_TRIM_REG); | ||
524 | v &= ~(REFO_TRIM_MASK << REFO_TRIM_SHIFT); | ||
525 | v |= trim << REFO_TRIM_SHIFT; | ||
526 | writel(v, refo->ctrl_reg + REFO_TRIM_REG); | ||
527 | |||
528 | /* enable & activate divider switching */ | ||
529 | writel(REFO_ON | REFO_DIVSW_EN, PIC32_SET(refo->ctrl_reg)); | ||
530 | |||
531 | /* wait till divswen is in-progress */ | ||
532 | err = readl_poll_timeout_atomic(refo->ctrl_reg, v, !(v & REFO_DIVSW_EN), | ||
533 | 1, LOCK_TIMEOUT_US); | ||
534 | /* leave the clk gated as it was */ | ||
535 | writel(REFO_ON, PIC32_CLR(refo->ctrl_reg)); | ||
536 | |||
537 | spin_unlock_irqrestore(&refo->core->reg_lock, flags); | ||
538 | |||
539 | return err; | ||
540 | } | ||
541 | |||
542 | static int roclk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
543 | unsigned long parent_rate) | ||
544 | { | ||
545 | u8 index = roclk_get_parent(hw); | ||
546 | |||
547 | return roclk_set_rate_and_parent(hw, rate, parent_rate, index); | ||
548 | } | ||
549 | |||
550 | const struct clk_ops pic32_roclk_ops = { | ||
551 | .enable = roclk_enable, | ||
552 | .disable = roclk_disable, | ||
553 | .is_enabled = roclk_is_enabled, | ||
554 | .get_parent = roclk_get_parent, | ||
555 | .set_parent = roclk_set_parent, | ||
556 | .determine_rate = roclk_determine_rate, | ||
557 | .recalc_rate = roclk_recalc_rate, | ||
558 | .set_rate_and_parent = roclk_set_rate_and_parent, | ||
559 | .set_rate = roclk_set_rate, | ||
560 | .init = roclk_init, | ||
561 | }; | ||
562 | |||
563 | struct clk *pic32_refo_clk_register(const struct pic32_ref_osc_data *data, | ||
564 | struct pic32_clk_common *core) | ||
565 | { | ||
566 | struct pic32_ref_osc *refo; | ||
567 | struct clk *clk; | ||
568 | |||
569 | refo = devm_kzalloc(core->dev, sizeof(*refo), GFP_KERNEL); | ||
570 | if (!refo) | ||
571 | return ERR_PTR(-ENOMEM); | ||
572 | |||
573 | refo->core = core; | ||
574 | refo->hw.init = &data->init_data; | ||
575 | refo->ctrl_reg = data->ctrl_reg + core->iobase; | ||
576 | refo->parent_map = data->parent_map; | ||
577 | |||
578 | clk = devm_clk_register(core->dev, &refo->hw); | ||
579 | if (IS_ERR(clk)) | ||
580 | dev_err(core->dev, "%s: clk_register() failed\n", __func__); | ||
581 | |||
582 | return clk; | ||
583 | } | ||
584 | |||
585 | struct pic32_sys_pll { | ||
586 | struct clk_hw hw; | ||
587 | void __iomem *ctrl_reg; | ||
588 | void __iomem *status_reg; | ||
589 | u32 lock_mask; | ||
590 | u32 idiv; /* PLL iclk divider, treated fixed */ | ||
591 | struct pic32_clk_common *core; | ||
592 | }; | ||
593 | |||
594 | #define clkhw_to_spll(_hw) container_of(_hw, struct pic32_sys_pll, hw) | ||
595 | |||
596 | static inline u32 spll_odiv_to_divider(u32 odiv) | ||
597 | { | ||
598 | odiv = clamp_val(odiv, PLL_ODIV_MIN, PLL_ODIV_MAX); | ||
599 | |||
600 | return 1 << odiv; | ||
601 | } | ||
602 | |||
603 | static unsigned long spll_calc_mult_div(struct pic32_sys_pll *pll, | ||
604 | unsigned long rate, | ||
605 | unsigned long parent_rate, | ||
606 | u32 *mult_p, u32 *odiv_p) | ||
607 | { | ||
608 | u32 mul, div, best_mul = 1, best_div = 1; | ||
609 | unsigned long new_rate, best_rate = rate; | ||
610 | unsigned int best_delta = -1, delta, match_found = 0; | ||
611 | u64 rate64; | ||
612 | |||
613 | parent_rate /= pll->idiv; | ||
614 | |||
615 | for (mul = 1; mul <= PLL_MULT_MAX; mul++) { | ||
616 | for (div = PLL_ODIV_MIN; div <= PLL_ODIV_MAX; div++) { | ||
617 | rate64 = parent_rate; | ||
618 | rate64 *= mul; | ||
619 | do_div(rate64, 1 << div); | ||
620 | new_rate = rate64; | ||
621 | delta = abs(rate - new_rate); | ||
622 | if ((new_rate >= rate) && (delta < best_delta)) { | ||
623 | best_delta = delta; | ||
624 | best_rate = new_rate; | ||
625 | best_mul = mul; | ||
626 | best_div = div; | ||
627 | match_found = 1; | ||
628 | } | ||
629 | } | ||
630 | } | ||
631 | |||
632 | if (!match_found) { | ||
633 | pr_warn("spll: no match found\n"); | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | pr_debug("rate %lu, par_rate %lu/mult %u, div %u, best_rate %lu\n", | ||
638 | rate, parent_rate, best_mul, best_div, best_rate); | ||
639 | |||
640 | if (mult_p) | ||
641 | *mult_p = best_mul - 1; | ||
642 | |||
643 | if (odiv_p) | ||
644 | *odiv_p = best_div; | ||
645 | |||
646 | return best_rate; | ||
647 | } | ||
648 | |||
649 | static unsigned long spll_clk_recalc_rate(struct clk_hw *hw, | ||
650 | unsigned long parent_rate) | ||
651 | { | ||
652 | struct pic32_sys_pll *pll = clkhw_to_spll(hw); | ||
653 | unsigned long pll_in_rate; | ||
654 | u32 mult, odiv, div, v; | ||
655 | u64 rate64; | ||
656 | |||
657 | v = readl(pll->ctrl_reg); | ||
658 | odiv = ((v >> PLL_ODIV_SHIFT) & PLL_ODIV_MASK); | ||
659 | mult = ((v >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; | ||
660 | div = spll_odiv_to_divider(odiv); | ||
661 | |||
662 | /* pll_in_rate = parent_rate / idiv | ||
663 | * pll_out_rate = pll_in_rate * mult / div; | ||
664 | */ | ||
665 | pll_in_rate = parent_rate / pll->idiv; | ||
666 | rate64 = pll_in_rate; | ||
667 | rate64 *= mult; | ||
668 | do_div(rate64, div); | ||
669 | |||
670 | return rate64; | ||
671 | } | ||
672 | |||
673 | static long spll_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
674 | unsigned long *parent_rate) | ||
675 | { | ||
676 | struct pic32_sys_pll *pll = clkhw_to_spll(hw); | ||
677 | |||
678 | return spll_calc_mult_div(pll, rate, *parent_rate, NULL, NULL); | ||
679 | } | ||
680 | |||
681 | static int spll_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
682 | unsigned long parent_rate) | ||
683 | { | ||
684 | struct pic32_sys_pll *pll = clkhw_to_spll(hw); | ||
685 | unsigned long ret, flags; | ||
686 | u32 mult, odiv, v; | ||
687 | int err; | ||
688 | |||
689 | ret = spll_calc_mult_div(pll, rate, parent_rate, &mult, &odiv); | ||
690 | if (!ret) | ||
691 | return -EINVAL; | ||
692 | |||
693 | /* | ||
694 | * We can't change SPLL counters when it is in-active use | ||
695 | * by SYSCLK. So check before applying new counters/rate. | ||
696 | */ | ||
697 | |||
698 | /* Is spll_clk active parent of sys_clk ? */ | ||
699 | if (unlikely(clk_hw_get_parent(pic32_sclk_hw) == hw)) { | ||
700 | pr_err("%s: failed, clk in-use\n", __func__); | ||
701 | return -EBUSY; | ||
702 | } | ||
703 | |||
704 | spin_lock_irqsave(&pll->core->reg_lock, flags); | ||
705 | |||
706 | /* apply new multiplier & divisor */ | ||
707 | v = readl(pll->ctrl_reg); | ||
708 | v &= ~(PLL_MULT_MASK << PLL_MULT_SHIFT); | ||
709 | v &= ~(PLL_ODIV_MASK << PLL_ODIV_SHIFT); | ||
710 | v |= (mult << PLL_MULT_SHIFT) | (odiv << PLL_ODIV_SHIFT); | ||
711 | |||
712 | /* sys unlock before write */ | ||
713 | pic32_syskey_unlock(); | ||
714 | |||
715 | writel(v, pll->ctrl_reg); | ||
716 | cpu_relax(); | ||
717 | |||
718 | /* insert few nops (5-stage) to ensure CPU does not hang */ | ||
719 | cpu_nop5(); | ||
720 | cpu_nop5(); | ||
721 | |||
722 | /* Wait until PLL is locked (maximum 100 usecs). */ | ||
723 | err = readl_poll_timeout_atomic(pll->status_reg, v, | ||
724 | v & pll->lock_mask, 1, 100); | ||
725 | spin_unlock_irqrestore(&pll->core->reg_lock, flags); | ||
726 | |||
727 | return err; | ||
728 | } | ||
729 | |||
730 | /* SPLL clock operation */ | ||
731 | const struct clk_ops pic32_spll_ops = { | ||
732 | .recalc_rate = spll_clk_recalc_rate, | ||
733 | .round_rate = spll_clk_round_rate, | ||
734 | .set_rate = spll_clk_set_rate, | ||
735 | }; | ||
736 | |||
737 | struct clk *pic32_spll_clk_register(const struct pic32_sys_pll_data *data, | ||
738 | struct pic32_clk_common *core) | ||
739 | { | ||
740 | struct pic32_sys_pll *spll; | ||
741 | struct clk *clk; | ||
742 | |||
743 | spll = devm_kzalloc(core->dev, sizeof(*spll), GFP_KERNEL); | ||
744 | if (!spll) | ||
745 | return ERR_PTR(-ENOMEM); | ||
746 | |||
747 | spll->core = core; | ||
748 | spll->hw.init = &data->init_data; | ||
749 | spll->ctrl_reg = data->ctrl_reg + core->iobase; | ||
750 | spll->status_reg = data->status_reg + core->iobase; | ||
751 | spll->lock_mask = data->lock_mask; | ||
752 | |||
753 | /* cache PLL idiv; PLL driver uses it as constant.*/ | ||
754 | spll->idiv = (readl(spll->ctrl_reg) >> PLL_IDIV_SHIFT) & PLL_IDIV_MASK; | ||
755 | spll->idiv += 1; | ||
756 | |||
757 | clk = devm_clk_register(core->dev, &spll->hw); | ||
758 | if (IS_ERR(clk)) | ||
759 | dev_err(core->dev, "sys_pll: clk_register() failed\n"); | ||
760 | |||
761 | return clk; | ||
762 | } | ||
763 | |||
764 | /* System mux clock(aka SCLK) */ | ||
765 | |||
766 | struct pic32_sys_clk { | ||
767 | struct clk_hw hw; | ||
768 | void __iomem *mux_reg; | ||
769 | void __iomem *slew_reg; | ||
770 | u32 slew_div; | ||
771 | const u32 *parent_map; | ||
772 | struct pic32_clk_common *core; | ||
773 | }; | ||
774 | |||
775 | #define clkhw_to_sys_clk(_hw) container_of(_hw, struct pic32_sys_clk, hw) | ||
776 | |||
777 | static unsigned long sclk_get_rate(struct clk_hw *hw, unsigned long parent_rate) | ||
778 | { | ||
779 | struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw); | ||
780 | u32 div; | ||
781 | |||
782 | div = (readl(sclk->slew_reg) >> SLEW_SYSDIV_SHIFT) & SLEW_SYSDIV; | ||
783 | div += 1; /* sys-div to divider */ | ||
784 | |||
785 | return parent_rate / div; | ||
786 | } | ||
787 | |||
788 | static long sclk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
789 | unsigned long *parent_rate) | ||
790 | { | ||
791 | return calc_best_divided_rate(rate, *parent_rate, SLEW_SYSDIV, 1); | ||
792 | } | ||
793 | |||
794 | static int sclk_set_rate(struct clk_hw *hw, | ||
795 | unsigned long rate, unsigned long parent_rate) | ||
796 | { | ||
797 | struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw); | ||
798 | unsigned long flags; | ||
799 | u32 v, div; | ||
800 | int err; | ||
801 | |||
802 | div = parent_rate / rate; | ||
803 | |||
804 | spin_lock_irqsave(&sclk->core->reg_lock, flags); | ||
805 | |||
806 | /* apply new div */ | ||
807 | v = readl(sclk->slew_reg); | ||
808 | v &= ~(SLEW_SYSDIV << SLEW_SYSDIV_SHIFT); | ||
809 | v |= (div - 1) << SLEW_SYSDIV_SHIFT; | ||
810 | |||
811 | pic32_syskey_unlock(); | ||
812 | |||
813 | writel(v, sclk->slew_reg); | ||
814 | |||
815 | /* wait until BUSY is cleared */ | ||
816 | err = readl_poll_timeout_atomic(sclk->slew_reg, v, | ||
817 | !(v & SLEW_BUSY), 1, LOCK_TIMEOUT_US); | ||
818 | |||
819 | spin_unlock_irqrestore(&sclk->core->reg_lock, flags); | ||
820 | |||
821 | return err; | ||
822 | } | ||
823 | |||
824 | static u8 sclk_get_parent(struct clk_hw *hw) | ||
825 | { | ||
826 | struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw); | ||
827 | u32 i, v; | ||
828 | |||
829 | v = (readl(sclk->mux_reg) >> OSC_CUR_SHIFT) & OSC_CUR_MASK; | ||
830 | |||
831 | if (!sclk->parent_map) | ||
832 | return v; | ||
833 | |||
834 | for (i = 0; i < clk_hw_get_num_parents(hw); i++) | ||
835 | if (sclk->parent_map[i] == v) | ||
836 | return i; | ||
837 | return -EINVAL; | ||
838 | } | ||
839 | |||
840 | static int sclk_set_parent(struct clk_hw *hw, u8 index) | ||
841 | { | ||
842 | struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw); | ||
843 | unsigned long flags; | ||
844 | u32 nosc, cosc, v; | ||
845 | int err; | ||
846 | |||
847 | spin_lock_irqsave(&sclk->core->reg_lock, flags); | ||
848 | |||
849 | /* find new_osc */ | ||
850 | nosc = sclk->parent_map ? sclk->parent_map[index] : index; | ||
851 | |||
852 | /* set new parent */ | ||
853 | v = readl(sclk->mux_reg); | ||
854 | v &= ~(OSC_NEW_MASK << OSC_NEW_SHIFT); | ||
855 | v |= nosc << OSC_NEW_SHIFT; | ||
856 | |||
857 | pic32_syskey_unlock(); | ||
858 | |||
859 | writel(v, sclk->mux_reg); | ||
860 | |||
861 | /* initate switch */ | ||
862 | writel(OSC_SWEN, PIC32_SET(sclk->mux_reg)); | ||
863 | cpu_relax(); | ||
864 | |||
865 | /* add nop to flush pipeline (as cpu_clk is in-flux) */ | ||
866 | cpu_nop5(); | ||
867 | |||
868 | /* wait for SWEN bit to clear */ | ||
869 | err = readl_poll_timeout_atomic(sclk->slew_reg, v, | ||
870 | !(v & OSC_SWEN), 1, LOCK_TIMEOUT_US); | ||
871 | |||
872 | spin_unlock_irqrestore(&sclk->core->reg_lock, flags); | ||
873 | |||
874 | /* | ||
875 | * SCLK clock-switching logic might reject a clock switching request | ||
876 | * if pre-requisites (like new clk_src not present or unstable) are | ||
877 | * not met. | ||
878 | * So confirm before claiming success. | ||
879 | */ | ||
880 | cosc = (readl(sclk->mux_reg) >> OSC_CUR_SHIFT) & OSC_CUR_MASK; | ||
881 | if (cosc != nosc) { | ||
882 | pr_err("%s: err, failed to set_parent() to %d, current %d\n", | ||
883 | clk_hw_get_name(hw), nosc, cosc); | ||
884 | err = -EBUSY; | ||
885 | } | ||
886 | |||
887 | return err; | ||
888 | } | ||
889 | |||
890 | static void sclk_init(struct clk_hw *hw) | ||
891 | { | ||
892 | struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw); | ||
893 | unsigned long flags; | ||
894 | u32 v; | ||
895 | |||
896 | /* Maintain reference to this clk, required in spll_clk_set_rate() */ | ||
897 | pic32_sclk_hw = hw; | ||
898 | |||
899 | /* apply slew divider on both up and down scaling */ | ||
900 | if (sclk->slew_div) { | ||
901 | spin_lock_irqsave(&sclk->core->reg_lock, flags); | ||
902 | v = readl(sclk->slew_reg); | ||
903 | v &= ~(SLEW_DIV << SLEW_DIV_SHIFT); | ||
904 | v |= sclk->slew_div << SLEW_DIV_SHIFT; | ||
905 | v |= SLEW_DOWNEN | SLEW_UPEN; | ||
906 | writel(v, sclk->slew_reg); | ||
907 | spin_unlock_irqrestore(&sclk->core->reg_lock, flags); | ||
908 | } | ||
909 | } | ||
910 | |||
911 | /* sclk with post-divider */ | ||
912 | const struct clk_ops pic32_sclk_ops = { | ||
913 | .get_parent = sclk_get_parent, | ||
914 | .set_parent = sclk_set_parent, | ||
915 | .round_rate = sclk_round_rate, | ||
916 | .set_rate = sclk_set_rate, | ||
917 | .recalc_rate = sclk_get_rate, | ||
918 | .init = sclk_init, | ||
919 | .determine_rate = __clk_mux_determine_rate, | ||
920 | }; | ||
921 | |||
922 | /* sclk with no slew and no post-divider */ | ||
923 | const struct clk_ops pic32_sclk_no_div_ops = { | ||
924 | .get_parent = sclk_get_parent, | ||
925 | .set_parent = sclk_set_parent, | ||
926 | .init = sclk_init, | ||
927 | .determine_rate = __clk_mux_determine_rate, | ||
928 | }; | ||
929 | |||
930 | struct clk *pic32_sys_clk_register(const struct pic32_sys_clk_data *data, | ||
931 | struct pic32_clk_common *core) | ||
932 | { | ||
933 | struct pic32_sys_clk *sclk; | ||
934 | struct clk *clk; | ||
935 | |||
936 | sclk = devm_kzalloc(core->dev, sizeof(*sclk), GFP_KERNEL); | ||
937 | if (!sclk) | ||
938 | return ERR_PTR(-ENOMEM); | ||
939 | |||
940 | sclk->core = core; | ||
941 | sclk->hw.init = &data->init_data; | ||
942 | sclk->mux_reg = data->mux_reg + core->iobase; | ||
943 | sclk->slew_reg = data->slew_reg + core->iobase; | ||
944 | sclk->slew_div = data->slew_div; | ||
945 | sclk->parent_map = data->parent_map; | ||
946 | |||
947 | clk = devm_clk_register(core->dev, &sclk->hw); | ||
948 | if (IS_ERR(clk)) | ||
949 | dev_err(core->dev, "%s: clk register failed\n", __func__); | ||
950 | |||
951 | return clk; | ||
952 | } | ||
953 | |||
954 | /* secondary oscillator */ | ||
955 | struct pic32_sec_osc { | ||
956 | struct clk_hw hw; | ||
957 | void __iomem *enable_reg; | ||
958 | void __iomem *status_reg; | ||
959 | u32 enable_mask; | ||
960 | u32 status_mask; | ||
961 | unsigned long fixed_rate; | ||
962 | struct pic32_clk_common *core; | ||
963 | }; | ||
964 | |||
965 | #define clkhw_to_sosc(_hw) container_of(_hw, struct pic32_sec_osc, hw) | ||
966 | static int sosc_clk_enable(struct clk_hw *hw) | ||
967 | { | ||
968 | struct pic32_sec_osc *sosc = clkhw_to_sosc(hw); | ||
969 | u32 v; | ||
970 | |||
971 | /* enable SOSC */ | ||
972 | pic32_syskey_unlock(); | ||
973 | writel(sosc->enable_mask, PIC32_SET(sosc->enable_reg)); | ||
974 | |||
975 | /* wait till warm-up period expires or ready-status is updated */ | ||
976 | return readl_poll_timeout_atomic(sosc->status_reg, v, | ||
977 | v & sosc->status_mask, 1, 100); | ||
978 | } | ||
979 | |||
980 | static void sosc_clk_disable(struct clk_hw *hw) | ||
981 | { | ||
982 | struct pic32_sec_osc *sosc = clkhw_to_sosc(hw); | ||
983 | |||
984 | pic32_syskey_unlock(); | ||
985 | writel(sosc->enable_mask, PIC32_CLR(sosc->enable_reg)); | ||
986 | } | ||
987 | |||
988 | static int sosc_clk_is_enabled(struct clk_hw *hw) | ||
989 | { | ||
990 | struct pic32_sec_osc *sosc = clkhw_to_sosc(hw); | ||
991 | u32 enabled, ready; | ||
992 | |||
993 | /* check enabled and ready status */ | ||
994 | enabled = readl(sosc->enable_reg) & sosc->enable_mask; | ||
995 | ready = readl(sosc->status_reg) & sosc->status_mask; | ||
996 | |||
997 | return enabled && ready; | ||
998 | } | ||
999 | |||
1000 | static unsigned long sosc_clk_calc_rate(struct clk_hw *hw, | ||
1001 | unsigned long parent_rate) | ||
1002 | { | ||
1003 | return clkhw_to_sosc(hw)->fixed_rate; | ||
1004 | } | ||
1005 | |||
1006 | const struct clk_ops pic32_sosc_ops = { | ||
1007 | .enable = sosc_clk_enable, | ||
1008 | .disable = sosc_clk_disable, | ||
1009 | .is_enabled = sosc_clk_is_enabled, | ||
1010 | .recalc_rate = sosc_clk_calc_rate, | ||
1011 | }; | ||
1012 | |||
1013 | struct clk *pic32_sosc_clk_register(const struct pic32_sec_osc_data *data, | ||
1014 | struct pic32_clk_common *core) | ||
1015 | { | ||
1016 | struct pic32_sec_osc *sosc; | ||
1017 | |||
1018 | sosc = devm_kzalloc(core->dev, sizeof(*sosc), GFP_KERNEL); | ||
1019 | if (!sosc) | ||
1020 | return ERR_PTR(-ENOMEM); | ||
1021 | |||
1022 | sosc->core = core; | ||
1023 | sosc->hw.init = &data->init_data; | ||
1024 | sosc->fixed_rate = data->fixed_rate; | ||
1025 | sosc->enable_mask = data->enable_mask; | ||
1026 | sosc->status_mask = data->status_mask; | ||
1027 | sosc->enable_reg = data->enable_reg + core->iobase; | ||
1028 | sosc->status_reg = data->status_reg + core->iobase; | ||
1029 | |||
1030 | return devm_clk_register(core->dev, &sosc->hw); | ||
1031 | } | ||
diff --git a/drivers/clk/microchip/clk-core.h b/drivers/clk/microchip/clk-core.h new file mode 100644 index 000000000000..856664277a29 --- /dev/null +++ b/drivers/clk/microchip/clk-core.h | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * Purna Chandra Mandal,<purna.mandal@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #ifndef __MICROCHIP_CLK_PIC32_H_ | ||
15 | #define __MICROCHIP_CLK_PIC32_H_ | ||
16 | |||
17 | #include <linux/clk-provider.h> | ||
18 | |||
19 | /* PIC32 clock data */ | ||
20 | struct pic32_clk_common { | ||
21 | struct device *dev; | ||
22 | void __iomem *iobase; | ||
23 | spinlock_t reg_lock; /* clock lock */ | ||
24 | }; | ||
25 | |||
26 | /* System PLL clock */ | ||
27 | struct pic32_sys_pll_data { | ||
28 | struct clk_init_data init_data; | ||
29 | const u32 ctrl_reg; | ||
30 | const u32 status_reg; | ||
31 | const u32 lock_mask; | ||
32 | }; | ||
33 | |||
34 | /* System clock */ | ||
35 | struct pic32_sys_clk_data { | ||
36 | struct clk_init_data init_data; | ||
37 | const u32 mux_reg; | ||
38 | const u32 slew_reg; | ||
39 | const u32 *parent_map; | ||
40 | const u32 slew_div; | ||
41 | }; | ||
42 | |||
43 | /* Reference Oscillator clock */ | ||
44 | struct pic32_ref_osc_data { | ||
45 | struct clk_init_data init_data; | ||
46 | const u32 ctrl_reg; | ||
47 | const u32 *parent_map; | ||
48 | }; | ||
49 | |||
50 | /* Peripheral Bus clock */ | ||
51 | struct pic32_periph_clk_data { | ||
52 | struct clk_init_data init_data; | ||
53 | const u32 ctrl_reg; | ||
54 | }; | ||
55 | |||
56 | /* External Secondary Oscillator clock */ | ||
57 | struct pic32_sec_osc_data { | ||
58 | struct clk_init_data init_data; | ||
59 | const u32 enable_reg; | ||
60 | const u32 status_reg; | ||
61 | const u32 enable_mask; | ||
62 | const u32 status_mask; | ||
63 | const unsigned long fixed_rate; | ||
64 | }; | ||
65 | |||
66 | extern const struct clk_ops pic32_pbclk_ops; | ||
67 | extern const struct clk_ops pic32_sclk_ops; | ||
68 | extern const struct clk_ops pic32_sclk_no_div_ops; | ||
69 | extern const struct clk_ops pic32_spll_ops; | ||
70 | extern const struct clk_ops pic32_roclk_ops; | ||
71 | extern const struct clk_ops pic32_sosc_ops; | ||
72 | |||
73 | struct clk *pic32_periph_clk_register(const struct pic32_periph_clk_data *data, | ||
74 | struct pic32_clk_common *core); | ||
75 | struct clk *pic32_refo_clk_register(const struct pic32_ref_osc_data *data, | ||
76 | struct pic32_clk_common *core); | ||
77 | struct clk *pic32_sys_clk_register(const struct pic32_sys_clk_data *data, | ||
78 | struct pic32_clk_common *core); | ||
79 | struct clk *pic32_spll_clk_register(const struct pic32_sys_pll_data *data, | ||
80 | struct pic32_clk_common *core); | ||
81 | struct clk *pic32_sosc_clk_register(const struct pic32_sec_osc_data *data, | ||
82 | struct pic32_clk_common *core); | ||
83 | |||
84 | #endif /* __MICROCHIP_CLK_PIC32_H_*/ | ||
diff --git a/drivers/clk/microchip/clk-pic32mzda.c b/drivers/clk/microchip/clk-pic32mzda.c new file mode 100644 index 000000000000..020a29acc5b0 --- /dev/null +++ b/drivers/clk/microchip/clk-pic32mzda.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /* | ||
2 | * Purna Chandra Mandal,<purna.mandal@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <dt-bindings/clock/microchip,pic32-clock.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/clkdev.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/of_platform.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <asm/traps.h> | ||
23 | |||
24 | #include "clk-core.h" | ||
25 | |||
26 | /* FRC Postscaler */ | ||
27 | #define OSC_FRCDIV_MASK 0x07 | ||
28 | #define OSC_FRCDIV_SHIFT 24 | ||
29 | |||
30 | /* SPLL fields */ | ||
31 | #define PLL_ICLK_MASK 0x01 | ||
32 | #define PLL_ICLK_SHIFT 7 | ||
33 | |||
34 | #define DECLARE_PERIPHERAL_CLOCK(__clk_name, __reg, __flags) \ | ||
35 | { \ | ||
36 | .ctrl_reg = (__reg), \ | ||
37 | .init_data = { \ | ||
38 | .name = (__clk_name), \ | ||
39 | .parent_names = (const char *[]) { \ | ||
40 | "sys_clk" \ | ||
41 | }, \ | ||
42 | .num_parents = 1, \ | ||
43 | .ops = &pic32_pbclk_ops, \ | ||
44 | .flags = (__flags), \ | ||
45 | }, \ | ||
46 | } | ||
47 | |||
48 | #define DECLARE_REFO_CLOCK(__clkid, __reg) \ | ||
49 | { \ | ||
50 | .ctrl_reg = (__reg), \ | ||
51 | .init_data = { \ | ||
52 | .name = "refo" #__clkid "_clk", \ | ||
53 | .parent_names = (const char *[]) { \ | ||
54 | "sys_clk", "pb1_clk", "posc_clk", \ | ||
55 | "frc_clk", "lprc_clk", "sosc_clk", \ | ||
56 | "sys_pll", "refi" #__clkid "_clk", \ | ||
57 | "bfrc_clk", \ | ||
58 | }, \ | ||
59 | .num_parents = 9, \ | ||
60 | .flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE,\ | ||
61 | .ops = &pic32_roclk_ops, \ | ||
62 | }, \ | ||
63 | .parent_map = (const u32[]) { \ | ||
64 | 0, 1, 2, 3, 4, 5, 7, 8, 9 \ | ||
65 | }, \ | ||
66 | } | ||
67 | |||
68 | static const struct pic32_ref_osc_data ref_clks[] = { | ||
69 | DECLARE_REFO_CLOCK(1, 0x80), | ||
70 | DECLARE_REFO_CLOCK(2, 0xa0), | ||
71 | DECLARE_REFO_CLOCK(3, 0xc0), | ||
72 | DECLARE_REFO_CLOCK(4, 0xe0), | ||
73 | DECLARE_REFO_CLOCK(5, 0x100), | ||
74 | }; | ||
75 | |||
76 | static const struct pic32_periph_clk_data periph_clocks[] = { | ||
77 | DECLARE_PERIPHERAL_CLOCK("pb1_clk", 0x140, 0), | ||
78 | DECLARE_PERIPHERAL_CLOCK("pb2_clk", 0x150, CLK_IGNORE_UNUSED), | ||
79 | DECLARE_PERIPHERAL_CLOCK("pb3_clk", 0x160, 0), | ||
80 | DECLARE_PERIPHERAL_CLOCK("pb4_clk", 0x170, 0), | ||
81 | DECLARE_PERIPHERAL_CLOCK("pb5_clk", 0x180, 0), | ||
82 | DECLARE_PERIPHERAL_CLOCK("pb6_clk", 0x190, 0), | ||
83 | DECLARE_PERIPHERAL_CLOCK("cpu_clk", 0x1a0, CLK_IGNORE_UNUSED), | ||
84 | }; | ||
85 | |||
86 | static const struct pic32_sys_clk_data sys_mux_clk = { | ||
87 | .slew_reg = 0x1c0, | ||
88 | .slew_div = 2, /* step of div_4 -> div_2 -> no_div */ | ||
89 | .init_data = { | ||
90 | .name = "sys_clk", | ||
91 | .parent_names = (const char *[]) { | ||
92 | "frcdiv_clk", "sys_pll", "posc_clk", | ||
93 | "sosc_clk", "lprc_clk", "frcdiv_clk", | ||
94 | }, | ||
95 | .num_parents = 6, | ||
96 | .ops = &pic32_sclk_ops, | ||
97 | }, | ||
98 | .parent_map = (const u32[]) { | ||
99 | 0, 1, 2, 4, 5, 7, | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static const struct pic32_sys_pll_data sys_pll = { | ||
104 | .ctrl_reg = 0x020, | ||
105 | .status_reg = 0x1d0, | ||
106 | .lock_mask = BIT(7), | ||
107 | .init_data = { | ||
108 | .name = "sys_pll", | ||
109 | .parent_names = (const char *[]) { | ||
110 | "spll_mux_clk" | ||
111 | }, | ||
112 | .num_parents = 1, | ||
113 | .ops = &pic32_spll_ops, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static const struct pic32_sec_osc_data sosc_clk = { | ||
118 | .status_reg = 0x1d0, | ||
119 | .enable_mask = BIT(1), | ||
120 | .status_mask = BIT(4), | ||
121 | .init_data = { | ||
122 | .name = "sosc_clk", | ||
123 | .parent_names = NULL, | ||
124 | .ops = &pic32_sosc_ops, | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | static int pic32mzda_critical_clks[] = { | ||
129 | PB2CLK, PB7CLK | ||
130 | }; | ||
131 | |||
132 | /* PIC32MZDA clock data */ | ||
133 | struct pic32mzda_clk_data { | ||
134 | struct clk *clks[MAXCLKS]; | ||
135 | struct pic32_clk_common core; | ||
136 | struct clk_onecell_data onecell_data; | ||
137 | struct notifier_block failsafe_notifier; | ||
138 | }; | ||
139 | |||
140 | static int pic32_fscm_nmi(struct notifier_block *nb, | ||
141 | unsigned long action, void *data) | ||
142 | { | ||
143 | struct pic32mzda_clk_data *cd; | ||
144 | |||
145 | cd = container_of(nb, struct pic32mzda_clk_data, failsafe_notifier); | ||
146 | |||
147 | /* SYSCLK is now running from BFRCCLK. Report clock failure. */ | ||
148 | if (readl(cd->core.iobase) & BIT(2)) | ||
149 | pr_alert("pic32-clk: FSCM detected clk failure.\n"); | ||
150 | |||
151 | /* TODO: detect reason of failure and recover accordingly */ | ||
152 | |||
153 | return NOTIFY_OK; | ||
154 | } | ||
155 | |||
156 | static int pic32mzda_clk_probe(struct platform_device *pdev) | ||
157 | { | ||
158 | const char *const pll_mux_parents[] = {"posc_clk", "frc_clk"}; | ||
159 | struct device_node *np = pdev->dev.of_node; | ||
160 | struct pic32mzda_clk_data *cd; | ||
161 | struct pic32_clk_common *core; | ||
162 | struct clk *pll_mux_clk, *clk; | ||
163 | struct clk **clks; | ||
164 | int nr_clks, i, ret; | ||
165 | |||
166 | cd = devm_kzalloc(&pdev->dev, sizeof(*cd), GFP_KERNEL); | ||
167 | if (!cd) | ||
168 | return -ENOMEM; | ||
169 | |||
170 | core = &cd->core; | ||
171 | core->iobase = of_io_request_and_map(np, 0, of_node_full_name(np)); | ||
172 | if (IS_ERR(core->iobase)) { | ||
173 | dev_err(&pdev->dev, "pic32-clk: failed to map registers\n"); | ||
174 | return PTR_ERR(core->iobase); | ||
175 | } | ||
176 | |||
177 | spin_lock_init(&core->reg_lock); | ||
178 | core->dev = &pdev->dev; | ||
179 | clks = &cd->clks[0]; | ||
180 | |||
181 | /* register fixed rate clocks */ | ||
182 | clks[POSCCLK] = clk_register_fixed_rate(&pdev->dev, "posc_clk", NULL, | ||
183 | CLK_IS_ROOT, 24000000); | ||
184 | clks[FRCCLK] = clk_register_fixed_rate(&pdev->dev, "frc_clk", NULL, | ||
185 | CLK_IS_ROOT, 8000000); | ||
186 | clks[BFRCCLK] = clk_register_fixed_rate(&pdev->dev, "bfrc_clk", NULL, | ||
187 | CLK_IS_ROOT, 8000000); | ||
188 | clks[LPRCCLK] = clk_register_fixed_rate(&pdev->dev, "lprc_clk", NULL, | ||
189 | CLK_IS_ROOT, 32000); | ||
190 | clks[UPLLCLK] = clk_register_fixed_rate(&pdev->dev, "usbphy_clk", NULL, | ||
191 | CLK_IS_ROOT, 24000000); | ||
192 | /* fixed rate (optional) clock */ | ||
193 | if (of_find_property(np, "microchip,pic32mzda-sosc", NULL)) { | ||
194 | pr_info("pic32-clk: dt requests SOSC.\n"); | ||
195 | clks[SOSCCLK] = pic32_sosc_clk_register(&sosc_clk, core); | ||
196 | } | ||
197 | /* divider clock */ | ||
198 | clks[FRCDIVCLK] = clk_register_divider(&pdev->dev, "frcdiv_clk", | ||
199 | "frc_clk", 0, | ||
200 | core->iobase, | ||
201 | OSC_FRCDIV_SHIFT, | ||
202 | OSC_FRCDIV_MASK, | ||
203 | CLK_DIVIDER_POWER_OF_TWO, | ||
204 | &core->reg_lock); | ||
205 | /* PLL ICLK mux */ | ||
206 | pll_mux_clk = clk_register_mux(&pdev->dev, "spll_mux_clk", | ||
207 | pll_mux_parents, 2, 0, | ||
208 | core->iobase + 0x020, | ||
209 | PLL_ICLK_SHIFT, 1, 0, &core->reg_lock); | ||
210 | if (IS_ERR(pll_mux_clk)) | ||
211 | pr_err("spll_mux_clk: clk register failed\n"); | ||
212 | |||
213 | /* PLL */ | ||
214 | clks[PLLCLK] = pic32_spll_clk_register(&sys_pll, core); | ||
215 | /* SYSTEM clock */ | ||
216 | clks[SCLK] = pic32_sys_clk_register(&sys_mux_clk, core); | ||
217 | /* Peripheral bus clocks */ | ||
218 | for (nr_clks = PB1CLK, i = 0; nr_clks <= PB7CLK; i++, nr_clks++) | ||
219 | clks[nr_clks] = pic32_periph_clk_register(&periph_clocks[i], | ||
220 | core); | ||
221 | /* Reference oscillator clock */ | ||
222 | for (nr_clks = REF1CLK, i = 0; nr_clks <= REF5CLK; i++, nr_clks++) | ||
223 | clks[nr_clks] = pic32_refo_clk_register(&ref_clks[i], core); | ||
224 | |||
225 | /* register clkdev */ | ||
226 | for (i = 0; i < MAXCLKS; i++) { | ||
227 | if (IS_ERR(clks[i])) | ||
228 | continue; | ||
229 | clk_register_clkdev(clks[i], NULL, __clk_get_name(clks[i])); | ||
230 | } | ||
231 | |||
232 | /* register clock provider */ | ||
233 | cd->onecell_data.clks = clks; | ||
234 | cd->onecell_data.clk_num = MAXCLKS; | ||
235 | ret = of_clk_add_provider(np, of_clk_src_onecell_get, | ||
236 | &cd->onecell_data); | ||
237 | if (ret) | ||
238 | return ret; | ||
239 | |||
240 | /* force enable critical clocks */ | ||
241 | for (i = 0; i < ARRAY_SIZE(pic32mzda_critical_clks); i++) { | ||
242 | clk = clks[pic32mzda_critical_clks[i]]; | ||
243 | if (clk_prepare_enable(clk)) | ||
244 | dev_err(&pdev->dev, "clk_prepare_enable(%s) failed\n", | ||
245 | __clk_get_name(clk)); | ||
246 | } | ||
247 | |||
248 | /* register NMI for failsafe clock monitor */ | ||
249 | cd->failsafe_notifier.notifier_call = pic32_fscm_nmi; | ||
250 | return register_nmi_notifier(&cd->failsafe_notifier); | ||
251 | } | ||
252 | |||
253 | static const struct of_device_id pic32mzda_clk_match_table[] = { | ||
254 | { .compatible = "microchip,pic32mzda-clk", }, | ||
255 | { } | ||
256 | }; | ||
257 | MODULE_DEVICE_TABLE(of, pic32mzda_clk_match_table); | ||
258 | |||
259 | static struct platform_driver pic32mzda_clk_driver = { | ||
260 | .probe = pic32mzda_clk_probe, | ||
261 | .driver = { | ||
262 | .name = "clk-pic32mzda", | ||
263 | .of_match_table = pic32mzda_clk_match_table, | ||
264 | }, | ||
265 | }; | ||
266 | |||
267 | static int __init microchip_pic32mzda_clk_init(void) | ||
268 | { | ||
269 | return platform_driver_register(&pic32mzda_clk_driver); | ||
270 | } | ||
271 | core_initcall(microchip_pic32mzda_clk_init); | ||
272 | |||
273 | MODULE_DESCRIPTION("Microchip PIC32MZDA Clock Driver"); | ||
274 | MODULE_LICENSE("GPL v2"); | ||
275 | MODULE_ALIAS("platform:clk-pic32mzda"); | ||
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index e1eb11ee3570..0a9b6a093646 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -102,7 +102,7 @@ obj-$(CONFIG_CRIS_MACH_ARTPEC3) += cris-artpec3-cpufreq.o | |||
102 | obj-$(CONFIG_ETRAXFS) += cris-etraxfs-cpufreq.o | 102 | obj-$(CONFIG_ETRAXFS) += cris-etraxfs-cpufreq.o |
103 | obj-$(CONFIG_IA64_ACPI_CPUFREQ) += ia64-acpi-cpufreq.o | 103 | obj-$(CONFIG_IA64_ACPI_CPUFREQ) += ia64-acpi-cpufreq.o |
104 | obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o | 104 | obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o |
105 | obj-$(CONFIG_LOONGSON1_CPUFREQ) += ls1x-cpufreq.o | 105 | obj-$(CONFIG_LOONGSON1_CPUFREQ) += loongson1-cpufreq.o |
106 | obj-$(CONFIG_SH_CPU_FREQ) += sh-cpufreq.o | 106 | obj-$(CONFIG_SH_CPU_FREQ) += sh-cpufreq.o |
107 | obj-$(CONFIG_SPARC_US2E_CPUFREQ) += sparc-us2e-cpufreq.o | 107 | obj-$(CONFIG_SPARC_US2E_CPUFREQ) += sparc-us2e-cpufreq.o |
108 | obj-$(CONFIG_SPARC_US3_CPUFREQ) += sparc-us3-cpufreq.o | 108 | obj-$(CONFIG_SPARC_US3_CPUFREQ) += sparc-us3-cpufreq.o |
diff --git a/drivers/cpufreq/ls1x-cpufreq.c b/drivers/cpufreq/loongson1-cpufreq.c index 262581b3318d..be89416e2358 100644 --- a/drivers/cpufreq/ls1x-cpufreq.c +++ b/drivers/cpufreq/loongson1-cpufreq.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * CPU Frequency Scaling for Loongson 1 SoC | 2 | * CPU Frequency Scaling for Loongson 1 SoC |
3 | * | 3 | * |
4 | * Copyright (C) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | 4 | * Copyright (C) 2014-2016 Zhang, Keguang <keguang.zhang@gmail.com> |
5 | * | 5 | * |
6 | * This file is licensed under the terms of the GNU General Public | 6 | * This file is licensed under the terms of the GNU General Public |
7 | * License version 2. This program is licensed "as is" without any | 7 | * License version 2. This program is licensed "as is" without any |
@@ -20,7 +20,7 @@ | |||
20 | #include <cpufreq.h> | 20 | #include <cpufreq.h> |
21 | #include <loongson1.h> | 21 | #include <loongson1.h> |
22 | 22 | ||
23 | static struct { | 23 | struct ls1x_cpufreq { |
24 | struct device *dev; | 24 | struct device *dev; |
25 | struct clk *clk; /* CPU clk */ | 25 | struct clk *clk; /* CPU clk */ |
26 | struct clk *mux_clk; /* MUX of CPU clk */ | 26 | struct clk *mux_clk; /* MUX of CPU clk */ |
@@ -28,7 +28,9 @@ static struct { | |||
28 | struct clk *osc_clk; /* OSC clk */ | 28 | struct clk *osc_clk; /* OSC clk */ |
29 | unsigned int max_freq; | 29 | unsigned int max_freq; |
30 | unsigned int min_freq; | 30 | unsigned int min_freq; |
31 | } ls1x_cpufreq; | 31 | }; |
32 | |||
33 | static struct ls1x_cpufreq *cpufreq; | ||
32 | 34 | ||
33 | static int ls1x_cpufreq_notifier(struct notifier_block *nb, | 35 | static int ls1x_cpufreq_notifier(struct notifier_block *nb, |
34 | unsigned long val, void *data) | 36 | unsigned long val, void *data) |
@@ -46,6 +48,7 @@ static struct notifier_block ls1x_cpufreq_notifier_block = { | |||
46 | static int ls1x_cpufreq_target(struct cpufreq_policy *policy, | 48 | static int ls1x_cpufreq_target(struct cpufreq_policy *policy, |
47 | unsigned int index) | 49 | unsigned int index) |
48 | { | 50 | { |
51 | struct device *cpu_dev = get_cpu_device(policy->cpu); | ||
49 | unsigned int old_freq, new_freq; | 52 | unsigned int old_freq, new_freq; |
50 | 53 | ||
51 | old_freq = policy->cur; | 54 | old_freq = policy->cur; |
@@ -60,53 +63,49 @@ static int ls1x_cpufreq_target(struct cpufreq_policy *policy, | |||
60 | * - Reparent CPU clk back to CPU DIV clk | 63 | * - Reparent CPU clk back to CPU DIV clk |
61 | */ | 64 | */ |
62 | 65 | ||
63 | dev_dbg(ls1x_cpufreq.dev, "%u KHz --> %u KHz\n", old_freq, new_freq); | 66 | clk_set_parent(policy->clk, cpufreq->osc_clk); |
64 | clk_set_parent(policy->clk, ls1x_cpufreq.osc_clk); | ||
65 | __raw_writel(__raw_readl(LS1X_CLK_PLL_DIV) | RST_CPU_EN | RST_CPU, | 67 | __raw_writel(__raw_readl(LS1X_CLK_PLL_DIV) | RST_CPU_EN | RST_CPU, |
66 | LS1X_CLK_PLL_DIV); | 68 | LS1X_CLK_PLL_DIV); |
67 | __raw_writel(__raw_readl(LS1X_CLK_PLL_DIV) & ~(RST_CPU_EN | RST_CPU), | 69 | __raw_writel(__raw_readl(LS1X_CLK_PLL_DIV) & ~(RST_CPU_EN | RST_CPU), |
68 | LS1X_CLK_PLL_DIV); | 70 | LS1X_CLK_PLL_DIV); |
69 | clk_set_rate(ls1x_cpufreq.mux_clk, new_freq * 1000); | 71 | clk_set_rate(cpufreq->mux_clk, new_freq * 1000); |
70 | clk_set_parent(policy->clk, ls1x_cpufreq.mux_clk); | 72 | clk_set_parent(policy->clk, cpufreq->mux_clk); |
73 | dev_dbg(cpu_dev, "%u KHz --> %u KHz\n", old_freq, new_freq); | ||
71 | 74 | ||
72 | return 0; | 75 | return 0; |
73 | } | 76 | } |
74 | 77 | ||
75 | static int ls1x_cpufreq_init(struct cpufreq_policy *policy) | 78 | static int ls1x_cpufreq_init(struct cpufreq_policy *policy) |
76 | { | 79 | { |
80 | struct device *cpu_dev = get_cpu_device(policy->cpu); | ||
77 | struct cpufreq_frequency_table *freq_tbl; | 81 | struct cpufreq_frequency_table *freq_tbl; |
78 | unsigned int pll_freq, freq; | 82 | unsigned int pll_freq, freq; |
79 | int steps, i, ret; | 83 | int steps, i, ret; |
80 | 84 | ||
81 | pll_freq = clk_get_rate(ls1x_cpufreq.pll_clk) / 1000; | 85 | pll_freq = clk_get_rate(cpufreq->pll_clk) / 1000; |
82 | 86 | ||
83 | steps = 1 << DIV_CPU_WIDTH; | 87 | steps = 1 << DIV_CPU_WIDTH; |
84 | freq_tbl = kzalloc(sizeof(*freq_tbl) * steps, GFP_KERNEL); | 88 | freq_tbl = kcalloc(steps, sizeof(*freq_tbl), GFP_KERNEL); |
85 | if (!freq_tbl) { | 89 | if (!freq_tbl) |
86 | dev_err(ls1x_cpufreq.dev, | 90 | return -ENOMEM; |
87 | "failed to alloc cpufreq_frequency_table\n"); | ||
88 | ret = -ENOMEM; | ||
89 | goto out; | ||
90 | } | ||
91 | 91 | ||
92 | for (i = 0; i < (steps - 1); i++) { | 92 | for (i = 0; i < (steps - 1); i++) { |
93 | freq = pll_freq / (i + 1); | 93 | freq = pll_freq / (i + 1); |
94 | if ((freq < ls1x_cpufreq.min_freq) || | 94 | if ((freq < cpufreq->min_freq) || (freq > cpufreq->max_freq)) |
95 | (freq > ls1x_cpufreq.max_freq)) | ||
96 | freq_tbl[i].frequency = CPUFREQ_ENTRY_INVALID; | 95 | freq_tbl[i].frequency = CPUFREQ_ENTRY_INVALID; |
97 | else | 96 | else |
98 | freq_tbl[i].frequency = freq; | 97 | freq_tbl[i].frequency = freq; |
99 | dev_dbg(ls1x_cpufreq.dev, | 98 | dev_dbg(cpu_dev, |
100 | "cpufreq table: index %d: frequency %d\n", i, | 99 | "cpufreq table: index %d: frequency %d\n", i, |
101 | freq_tbl[i].frequency); | 100 | freq_tbl[i].frequency); |
102 | } | 101 | } |
103 | freq_tbl[i].frequency = CPUFREQ_TABLE_END; | 102 | freq_tbl[i].frequency = CPUFREQ_TABLE_END; |
104 | 103 | ||
105 | policy->clk = ls1x_cpufreq.clk; | 104 | policy->clk = cpufreq->clk; |
106 | ret = cpufreq_generic_init(policy, freq_tbl, 0); | 105 | ret = cpufreq_generic_init(policy, freq_tbl, 0); |
107 | if (ret) | 106 | if (ret) |
108 | kfree(freq_tbl); | 107 | kfree(freq_tbl); |
109 | out: | 108 | |
110 | return ret; | 109 | return ret; |
111 | } | 110 | } |
112 | 111 | ||
@@ -138,85 +137,86 @@ static int ls1x_cpufreq_remove(struct platform_device *pdev) | |||
138 | 137 | ||
139 | static int ls1x_cpufreq_probe(struct platform_device *pdev) | 138 | static int ls1x_cpufreq_probe(struct platform_device *pdev) |
140 | { | 139 | { |
141 | struct plat_ls1x_cpufreq *pdata = pdev->dev.platform_data; | 140 | struct plat_ls1x_cpufreq *pdata = dev_get_platdata(&pdev->dev); |
142 | struct clk *clk; | 141 | struct clk *clk; |
143 | int ret; | 142 | int ret; |
144 | 143 | ||
145 | if (!pdata || !pdata->clk_name || !pdata->osc_clk_name) | 144 | if (!pdata || !pdata->clk_name || !pdata->osc_clk_name) { |
145 | dev_err(&pdev->dev, "platform data missing\n"); | ||
146 | return -EINVAL; | 146 | return -EINVAL; |
147 | } | ||
147 | 148 | ||
148 | ls1x_cpufreq.dev = &pdev->dev; | 149 | cpufreq = |
150 | devm_kzalloc(&pdev->dev, sizeof(struct ls1x_cpufreq), GFP_KERNEL); | ||
151 | if (!cpufreq) | ||
152 | return -ENOMEM; | ||
153 | |||
154 | cpufreq->dev = &pdev->dev; | ||
149 | 155 | ||
150 | clk = devm_clk_get(&pdev->dev, pdata->clk_name); | 156 | clk = devm_clk_get(&pdev->dev, pdata->clk_name); |
151 | if (IS_ERR(clk)) { | 157 | if (IS_ERR(clk)) { |
152 | dev_err(ls1x_cpufreq.dev, "unable to get %s clock\n", | 158 | dev_err(&pdev->dev, "unable to get %s clock\n", |
153 | pdata->clk_name); | 159 | pdata->clk_name); |
154 | ret = PTR_ERR(clk); | 160 | return PTR_ERR(clk); |
155 | goto out; | ||
156 | } | 161 | } |
157 | ls1x_cpufreq.clk = clk; | 162 | cpufreq->clk = clk; |
158 | 163 | ||
159 | clk = clk_get_parent(clk); | 164 | clk = clk_get_parent(clk); |
160 | if (IS_ERR(clk)) { | 165 | if (IS_ERR(clk)) { |
161 | dev_err(ls1x_cpufreq.dev, "unable to get parent of %s clock\n", | 166 | dev_err(&pdev->dev, "unable to get parent of %s clock\n", |
162 | __clk_get_name(ls1x_cpufreq.clk)); | 167 | __clk_get_name(cpufreq->clk)); |
163 | ret = PTR_ERR(clk); | 168 | return PTR_ERR(clk); |
164 | goto out; | ||
165 | } | 169 | } |
166 | ls1x_cpufreq.mux_clk = clk; | 170 | cpufreq->mux_clk = clk; |
167 | 171 | ||
168 | clk = clk_get_parent(clk); | 172 | clk = clk_get_parent(clk); |
169 | if (IS_ERR(clk)) { | 173 | if (IS_ERR(clk)) { |
170 | dev_err(ls1x_cpufreq.dev, "unable to get parent of %s clock\n", | 174 | dev_err(&pdev->dev, "unable to get parent of %s clock\n", |
171 | __clk_get_name(ls1x_cpufreq.mux_clk)); | 175 | __clk_get_name(cpufreq->mux_clk)); |
172 | ret = PTR_ERR(clk); | 176 | return PTR_ERR(clk); |
173 | goto out; | ||
174 | } | 177 | } |
175 | ls1x_cpufreq.pll_clk = clk; | 178 | cpufreq->pll_clk = clk; |
176 | 179 | ||
177 | clk = devm_clk_get(&pdev->dev, pdata->osc_clk_name); | 180 | clk = devm_clk_get(&pdev->dev, pdata->osc_clk_name); |
178 | if (IS_ERR(clk)) { | 181 | if (IS_ERR(clk)) { |
179 | dev_err(ls1x_cpufreq.dev, "unable to get %s clock\n", | 182 | dev_err(&pdev->dev, "unable to get %s clock\n", |
180 | pdata->osc_clk_name); | 183 | pdata->osc_clk_name); |
181 | ret = PTR_ERR(clk); | 184 | return PTR_ERR(clk); |
182 | goto out; | ||
183 | } | 185 | } |
184 | ls1x_cpufreq.osc_clk = clk; | 186 | cpufreq->osc_clk = clk; |
185 | 187 | ||
186 | ls1x_cpufreq.max_freq = pdata->max_freq; | 188 | cpufreq->max_freq = pdata->max_freq; |
187 | ls1x_cpufreq.min_freq = pdata->min_freq; | 189 | cpufreq->min_freq = pdata->min_freq; |
188 | 190 | ||
189 | ret = cpufreq_register_driver(&ls1x_cpufreq_driver); | 191 | ret = cpufreq_register_driver(&ls1x_cpufreq_driver); |
190 | if (ret) { | 192 | if (ret) { |
191 | dev_err(ls1x_cpufreq.dev, | 193 | dev_err(&pdev->dev, |
192 | "failed to register cpufreq driver: %d\n", ret); | 194 | "failed to register CPUFreq driver: %d\n", ret); |
193 | goto out; | 195 | return ret; |
194 | } | 196 | } |
195 | 197 | ||
196 | ret = cpufreq_register_notifier(&ls1x_cpufreq_notifier_block, | 198 | ret = cpufreq_register_notifier(&ls1x_cpufreq_notifier_block, |
197 | CPUFREQ_TRANSITION_NOTIFIER); | 199 | CPUFREQ_TRANSITION_NOTIFIER); |
198 | 200 | ||
199 | if (!ret) | 201 | if (ret) { |
200 | goto out; | 202 | dev_err(&pdev->dev, |
201 | 203 | "failed to register CPUFreq notifier: %d\n",ret); | |
202 | dev_err(ls1x_cpufreq.dev, "failed to register cpufreq notifier: %d\n", | 204 | cpufreq_unregister_driver(&ls1x_cpufreq_driver); |
203 | ret); | 205 | } |
204 | 206 | ||
205 | cpufreq_unregister_driver(&ls1x_cpufreq_driver); | ||
206 | out: | ||
207 | return ret; | 207 | return ret; |
208 | } | 208 | } |
209 | 209 | ||
210 | static struct platform_driver ls1x_cpufreq_platdrv = { | 210 | static struct platform_driver ls1x_cpufreq_platdrv = { |
211 | .driver = { | 211 | .probe = ls1x_cpufreq_probe, |
212 | .remove = ls1x_cpufreq_remove, | ||
213 | .driver = { | ||
212 | .name = "ls1x-cpufreq", | 214 | .name = "ls1x-cpufreq", |
213 | }, | 215 | }, |
214 | .probe = ls1x_cpufreq_probe, | ||
215 | .remove = ls1x_cpufreq_remove, | ||
216 | }; | 216 | }; |
217 | 217 | ||
218 | module_platform_driver(ls1x_cpufreq_platdrv); | 218 | module_platform_driver(ls1x_cpufreq_platdrv); |
219 | 219 | ||
220 | MODULE_AUTHOR("Kelvin Cheung <keguang.zhang@gmail.com>"); | 220 | MODULE_AUTHOR("Kelvin Cheung <keguang.zhang@gmail.com>"); |
221 | MODULE_DESCRIPTION("Loongson 1 CPUFreq driver"); | 221 | MODULE_DESCRIPTION("Loongson1 CPUFreq driver"); |
222 | MODULE_LICENSE("GPL"); | 222 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/firmware/broadcom/Kconfig b/drivers/firmware/broadcom/Kconfig index 6bed119930dd..3c7e5b741e37 100644 --- a/drivers/firmware/broadcom/Kconfig +++ b/drivers/firmware/broadcom/Kconfig | |||
@@ -9,3 +9,14 @@ config BCM47XX_NVRAM | |||
9 | This driver provides an easy way to get value of requested parameter. | 9 | This driver provides an easy way to get value of requested parameter. |
10 | It simply reads content of NVRAM and parses it. It doesn't control any | 10 | It simply reads content of NVRAM and parses it. It doesn't control any |
11 | hardware part itself. | 11 | hardware part itself. |
12 | |||
13 | config BCM47XX_SPROM | ||
14 | bool "Broadcom SPROM driver" | ||
15 | depends on BCM47XX_NVRAM | ||
16 | help | ||
17 | Broadcom devices store configuration data in SPROM. Accessing it is | ||
18 | specific to the bus host type, e.g. PCI(e) devices have it mapped in | ||
19 | a PCI BAR. | ||
20 | In case of SoC devices SPROM content is stored on a flash used by | ||
21 | bootloader firmware CFE. This driver provides method to ssb and bcma | ||
22 | drivers to read SPROM on SoC. | ||
diff --git a/drivers/firmware/broadcom/Makefile b/drivers/firmware/broadcom/Makefile index d0e683583cd6..f93efc479b8b 100644 --- a/drivers/firmware/broadcom/Makefile +++ b/drivers/firmware/broadcom/Makefile | |||
@@ -1 +1,2 @@ | |||
1 | obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx_nvram.o | 1 | obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx_nvram.o |
2 | obj-$(CONFIG_BCM47XX_SPROM) += bcm47xx_sprom.o | ||
diff --git a/arch/mips/bcm47xx/sprom.c b/drivers/firmware/broadcom/bcm47xx_sprom.c index ca7ad131d057..b6eb875d4af3 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/drivers/firmware/broadcom/bcm47xx_sprom.c | |||
@@ -26,9 +26,11 @@ | |||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 26 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <bcm47xx.h> | 29 | #include <linux/bcm47xx_nvram.h> |
30 | #include <linux/if_ether.h> | 30 | #include <linux/bcma/bcma.h> |
31 | #include <linux/etherdevice.h> | 31 | #include <linux/etherdevice.h> |
32 | #include <linux/if_ether.h> | ||
33 | #include <linux/ssb/ssb.h> | ||
32 | 34 | ||
33 | static void create_key(const char *prefix, const char *postfix, | 35 | static void create_key(const char *prefix, const char *postfix, |
34 | const char *name, char *buf, int len) | 36 | const char *name, char *buf, int len) |
@@ -599,7 +601,7 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, | |||
599 | bcm47xx_sprom_fill_auto(sprom, prefix, fallback); | 601 | bcm47xx_sprom_fill_auto(sprom, prefix, fallback); |
600 | } | 602 | } |
601 | 603 | ||
602 | #if defined(CONFIG_BCM47XX_SSB) | 604 | #if IS_BUILTIN(CONFIG_SSB) && IS_ENABLED(CONFIG_SSB_SPROM) |
603 | static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) | 605 | static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) |
604 | { | 606 | { |
605 | char prefix[10]; | 607 | char prefix[10]; |
@@ -622,7 +624,7 @@ static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) | |||
622 | } | 624 | } |
623 | #endif | 625 | #endif |
624 | 626 | ||
625 | #if defined(CONFIG_BCM47XX_BCMA) | 627 | #if IS_BUILTIN(CONFIG_BCMA) |
626 | /* | 628 | /* |
627 | * Having many NVRAM entries for PCI devices led to repeating prefixes like | 629 | * Having many NVRAM entries for PCI devices led to repeating prefixes like |
628 | * pci/1/1/ all the time and wasting flash space. So at some point Broadcom | 630 | * pci/1/1/ all the time and wasting flash space. So at some point Broadcom |
@@ -706,19 +708,30 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | |||
706 | } | 708 | } |
707 | #endif | 709 | #endif |
708 | 710 | ||
711 | static unsigned int bcm47xx_sprom_registered; | ||
712 | |||
709 | /* | 713 | /* |
710 | * On bcm47xx we need to register SPROM fallback handler very early, so we can't | 714 | * On bcm47xx we need to register SPROM fallback handler very early, so we can't |
711 | * use anything like platform device / driver for this. | 715 | * use anything like platform device / driver for this. |
712 | */ | 716 | */ |
713 | void bcm47xx_sprom_register_fallbacks(void) | 717 | int bcm47xx_sprom_register_fallbacks(void) |
714 | { | 718 | { |
715 | #if defined(CONFIG_BCM47XX_SSB) | 719 | if (bcm47xx_sprom_registered) |
720 | return 0; | ||
721 | |||
722 | #if IS_BUILTIN(CONFIG_SSB) && IS_ENABLED(CONFIG_SSB_SPROM) | ||
716 | if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) | 723 | if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) |
717 | pr_warn("Failed to register ssb SPROM handler\n"); | 724 | pr_warn("Failed to register ssb SPROM handler\n"); |
718 | #endif | 725 | #endif |
719 | 726 | ||
720 | #if defined(CONFIG_BCM47XX_BCMA) | 727 | #if IS_BUILTIN(CONFIG_BCMA) |
721 | if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) | 728 | if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) |
722 | pr_warn("Failed to register bcma SPROM handler\n"); | 729 | pr_warn("Failed to register bcma SPROM handler\n"); |
723 | #endif | 730 | #endif |
731 | |||
732 | bcm47xx_sprom_registered = 1; | ||
733 | |||
734 | return 0; | ||
724 | } | 735 | } |
736 | |||
737 | fs_initcall(bcm47xx_sprom_register_fallbacks); | ||
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 4dffccf532a2..c089f49b63fb 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c | |||
@@ -197,7 +197,7 @@ void gic_write_cpu_compare(cycle_t cnt, int cpu) | |||
197 | 197 | ||
198 | local_irq_save(flags); | 198 | local_irq_save(flags); |
199 | 199 | ||
200 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu); | 200 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), mips_cm_vp_id(cpu)); |
201 | 201 | ||
202 | if (mips_cm_is64) { | 202 | if (mips_cm_is64) { |
203 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt); | 203 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt); |
@@ -246,6 +246,14 @@ void gic_stop_count(void) | |||
246 | 246 | ||
247 | #endif | 247 | #endif |
248 | 248 | ||
249 | unsigned gic_read_local_vp_id(void) | ||
250 | { | ||
251 | unsigned long ident; | ||
252 | |||
253 | ident = gic_read(GIC_REG(VPE_LOCAL, GIC_VP_IDENT)); | ||
254 | return ident & GIC_VP_IDENT_VCNUM_MSK; | ||
255 | } | ||
256 | |||
249 | static bool gic_local_irq_is_routable(int intr) | 257 | static bool gic_local_irq_is_routable(int intr) |
250 | { | 258 | { |
251 | u32 vpe_ctl; | 259 | u32 vpe_ctl; |
@@ -553,7 +561,8 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d) | |||
553 | 561 | ||
554 | spin_lock_irqsave(&gic_lock, flags); | 562 | spin_lock_irqsave(&gic_lock, flags); |
555 | for (i = 0; i < gic_vpes; i++) { | 563 | for (i = 0; i < gic_vpes; i++) { |
556 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | 564 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), |
565 | mips_cm_vp_id(i)); | ||
557 | gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr); | 566 | gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr); |
558 | } | 567 | } |
559 | spin_unlock_irqrestore(&gic_lock, flags); | 568 | spin_unlock_irqrestore(&gic_lock, flags); |
@@ -567,7 +576,8 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d) | |||
567 | 576 | ||
568 | spin_lock_irqsave(&gic_lock, flags); | 577 | spin_lock_irqsave(&gic_lock, flags); |
569 | for (i = 0; i < gic_vpes; i++) { | 578 | for (i = 0; i < gic_vpes; i++) { |
570 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | 579 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), |
580 | mips_cm_vp_id(i)); | ||
571 | gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr); | 581 | gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr); |
572 | } | 582 | } |
573 | spin_unlock_irqrestore(&gic_lock, flags); | 583 | spin_unlock_irqrestore(&gic_lock, flags); |
@@ -607,7 +617,8 @@ static void __init gic_basic_init(void) | |||
607 | for (i = 0; i < gic_vpes; i++) { | 617 | for (i = 0; i < gic_vpes; i++) { |
608 | unsigned int j; | 618 | unsigned int j; |
609 | 619 | ||
610 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | 620 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), |
621 | mips_cm_vp_id(i)); | ||
611 | for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) { | 622 | for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) { |
612 | if (!gic_local_irq_is_routable(j)) | 623 | if (!gic_local_irq_is_routable(j)) |
613 | continue; | 624 | continue; |
@@ -652,7 +663,8 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, | |||
652 | for (i = 0; i < gic_vpes; i++) { | 663 | for (i = 0; i < gic_vpes; i++) { |
653 | u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; | 664 | u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; |
654 | 665 | ||
655 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | 666 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), |
667 | mips_cm_vp_id(i)); | ||
656 | 668 | ||
657 | switch (intr) { | 669 | switch (intr) { |
658 | case GIC_LOCAL_INT_WD: | 670 | case GIC_LOCAL_INT_WD: |
diff --git a/drivers/platform/mips/Kconfig b/drivers/platform/mips/Kconfig index 125e569017be..b3ae30a4c67b 100644 --- a/drivers/platform/mips/Kconfig +++ b/drivers/platform/mips/Kconfig | |||
@@ -15,10 +15,6 @@ menuconfig MIPS_PLATFORM_DEVICES | |||
15 | 15 | ||
16 | if MIPS_PLATFORM_DEVICES | 16 | if MIPS_PLATFORM_DEVICES |
17 | 17 | ||
18 | config MIPS_ACPI | ||
19 | bool | ||
20 | default y if LOONGSON_MACH3X | ||
21 | |||
22 | config CPU_HWMON | 18 | config CPU_HWMON |
23 | tristate "Loongson CPU HWMon Driver" | 19 | tristate "Loongson CPU HWMon Driver" |
24 | depends on LOONGSON_MACH3X | 20 | depends on LOONGSON_MACH3X |
diff --git a/drivers/platform/mips/Makefile b/drivers/platform/mips/Makefile index 43412849b195..8dfd03924c37 100644 --- a/drivers/platform/mips/Makefile +++ b/drivers/platform/mips/Makefile | |||
@@ -1,2 +1 @@ | |||
1 | obj-$(CONFIG_MIPS_ACPI) += acpi_init.o | ||
2 | obj-$(CONFIG_CPU_HWMON) += cpu_hwmon.o | obj-$(CONFIG_CPU_HWMON) += cpu_hwmon.o | |
diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c index 4993e19f1531..4300a558d0f3 100644 --- a/drivers/platform/mips/cpu_hwmon.c +++ b/drivers/platform/mips/cpu_hwmon.c | |||
@@ -20,9 +20,9 @@ int loongson3_cpu_temp(int cpu) | |||
20 | u32 reg; | 20 | u32 reg; |
21 | 21 | ||
22 | reg = LOONGSON_CHIPTEMP(cpu); | 22 | reg = LOONGSON_CHIPTEMP(cpu); |
23 | if (loongson_sysconf.cputype == Loongson_3A) | 23 | if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) |
24 | reg = (reg >> 8) & 0xff; | 24 | reg = (reg >> 8) & 0xff; |
25 | else if (loongson_sysconf.cputype == Loongson_3B) | 25 | else |
26 | reg = ((reg >> 8) & 0xff) - 100; | 26 | reg = ((reg >> 8) & 0xff) - 100; |
27 | 27 | ||
28 | return (int)reg * 1000; | 28 | return (int)reg * 1000; |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 13d4ed6caac4..7711b260dacf 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -900,6 +900,27 @@ config SERIAL_SGI_L1_CONSOLE | |||
900 | controller serial port as your console (you want this!), | 900 | controller serial port as your console (you want this!), |
901 | say Y. Otherwise, say N. | 901 | say Y. Otherwise, say N. |
902 | 902 | ||
903 | config SERIAL_PIC32 | ||
904 | tristate "Microchip PIC32 serial support" | ||
905 | depends on MACH_PIC32 | ||
906 | select SERIAL_CORE | ||
907 | help | ||
908 | If you have a PIC32, this driver supports the serial ports. | ||
909 | |||
910 | Say Y or M to use PIC32 serial ports, otherwise say N. Note that | ||
911 | to use a serial port as a console, this must be included in kernel and | ||
912 | not as a module. | ||
913 | |||
914 | config SERIAL_PIC32_CONSOLE | ||
915 | bool "PIC32 serial console support" | ||
916 | depends on SERIAL_PIC32 | ||
917 | select SERIAL_CORE_CONSOLE | ||
918 | help | ||
919 | If you have a PIC32, this driver supports the putting a console on one | ||
920 | of the serial ports. | ||
921 | |||
922 | Say Y to use the PIC32 console, otherwise say N. | ||
923 | |||
903 | config SERIAL_MPC52xx | 924 | config SERIAL_MPC52xx |
904 | tristate "Freescale MPC52xx/MPC512x family PSC serial support" | 925 | tristate "Freescale MPC52xx/MPC512x family PSC serial support" |
905 | depends on PPC_MPC52xx || PPC_MPC512x | 926 | depends on PPC_MPC52xx || PPC_MPC512x |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 8c261adac04e..74914aafac61 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -91,6 +91,7 @@ obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o | |||
91 | obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o | 91 | obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o |
92 | obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o | 92 | obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o |
93 | obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o | 93 | obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o |
94 | obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o | ||
94 | 95 | ||
95 | # GPIOLIB helpers for modem control lines | 96 | # GPIOLIB helpers for modem control lines |
96 | obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o | 97 | obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o |
diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c new file mode 100644 index 000000000000..62a43bf5698e --- /dev/null +++ b/drivers/tty/serial/pic32_uart.c | |||
@@ -0,0 +1,960 @@ | |||
1 | /* | ||
2 | * PIC32 Integrated Serial Driver. | ||
3 | * | ||
4 | * Copyright (C) 2015 Microchip Technology, Inc. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Sorin-Andrei Pistirica <andrei.pistirica@microchip.com> | ||
8 | * | ||
9 | * Licensed under GPLv2 or later. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_device.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | #include <linux/of_gpio.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/console.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/tty.h> | ||
24 | #include <linux/tty_flip.h> | ||
25 | #include <linux/serial_core.h> | ||
26 | #include <linux/delay.h> | ||
27 | |||
28 | #include <asm/mach-pic32/pic32.h> | ||
29 | #include "pic32_uart.h" | ||
30 | |||
31 | /* UART name and device definitions */ | ||
32 | #define PIC32_DEV_NAME "pic32-uart" | ||
33 | #define PIC32_MAX_UARTS 6 | ||
34 | #define PIC32_SDEV_NAME "ttyPIC" | ||
35 | |||
36 | /* pic32_sport pointer for console use */ | ||
37 | static struct pic32_sport *pic32_sports[PIC32_MAX_UARTS]; | ||
38 | |||
39 | static inline void pic32_wait_deplete_txbuf(struct pic32_sport *sport) | ||
40 | { | ||
41 | /* wait for tx empty, otherwise chars will be lost or corrupted */ | ||
42 | while (!(pic32_uart_readl(sport, PIC32_UART_STA) & PIC32_UART_STA_TRMT)) | ||
43 | udelay(1); | ||
44 | } | ||
45 | |||
46 | static inline int pic32_enable_clock(struct pic32_sport *sport) | ||
47 | { | ||
48 | int ret = clk_prepare_enable(sport->clk); | ||
49 | |||
50 | if (ret) | ||
51 | return ret; | ||
52 | |||
53 | sport->ref_clk++; | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static inline void pic32_disable_clock(struct pic32_sport *sport) | ||
58 | { | ||
59 | sport->ref_clk--; | ||
60 | clk_disable_unprepare(sport->clk); | ||
61 | } | ||
62 | |||
63 | /* serial core request to check if uart tx buffer is empty */ | ||
64 | static unsigned int pic32_uart_tx_empty(struct uart_port *port) | ||
65 | { | ||
66 | struct pic32_sport *sport = to_pic32_sport(port); | ||
67 | u32 val = pic32_uart_readl(sport, PIC32_UART_STA); | ||
68 | |||
69 | return (val & PIC32_UART_STA_TRMT) ? 1 : 0; | ||
70 | } | ||
71 | |||
72 | /* serial core request to set UART outputs */ | ||
73 | static void pic32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
74 | { | ||
75 | struct pic32_sport *sport = to_pic32_sport(port); | ||
76 | |||
77 | /* set loopback mode */ | ||
78 | if (mctrl & TIOCM_LOOP) | ||
79 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE), | ||
80 | PIC32_UART_MODE_LPBK); | ||
81 | else | ||
82 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
83 | PIC32_UART_MODE_LPBK); | ||
84 | } | ||
85 | |||
86 | /* get the state of CTS input pin for this port */ | ||
87 | static unsigned int get_cts_state(struct pic32_sport *sport) | ||
88 | { | ||
89 | /* read and invert UxCTS */ | ||
90 | if (gpio_is_valid(sport->cts_gpio)) | ||
91 | return !gpio_get_value(sport->cts_gpio); | ||
92 | |||
93 | return 1; | ||
94 | } | ||
95 | |||
96 | /* serial core request to return the state of misc UART input pins */ | ||
97 | static unsigned int pic32_uart_get_mctrl(struct uart_port *port) | ||
98 | { | ||
99 | struct pic32_sport *sport = to_pic32_sport(port); | ||
100 | unsigned int mctrl = 0; | ||
101 | |||
102 | if (!sport->hw_flow_ctrl) | ||
103 | mctrl |= TIOCM_CTS; | ||
104 | else if (get_cts_state(sport)) | ||
105 | mctrl |= TIOCM_CTS; | ||
106 | |||
107 | /* DSR and CD are not supported in PIC32, so return 1 | ||
108 | * RI is not supported in PIC32, so return 0 | ||
109 | */ | ||
110 | mctrl |= TIOCM_CD; | ||
111 | mctrl |= TIOCM_DSR; | ||
112 | |||
113 | return mctrl; | ||
114 | } | ||
115 | |||
116 | /* stop tx and start tx are not called in pairs, therefore a flag indicates | ||
117 | * the status of irq to control the irq-depth. | ||
118 | */ | ||
119 | static inline void pic32_uart_irqtxen(struct pic32_sport *sport, u8 en) | ||
120 | { | ||
121 | if (en && !tx_irq_enabled(sport)) { | ||
122 | enable_irq(sport->irq_tx); | ||
123 | tx_irq_enabled(sport) = 1; | ||
124 | } else if (!en && tx_irq_enabled(sport)) { | ||
125 | /* use disable_irq_nosync() and not disable_irq() to avoid self | ||
126 | * imposed deadlock by not waiting for irq handler to end, | ||
127 | * since this callback is called from interrupt context. | ||
128 | */ | ||
129 | disable_irq_nosync(sport->irq_tx); | ||
130 | tx_irq_enabled(sport) = 0; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | /* serial core request to disable tx ASAP (used for flow control) */ | ||
135 | static void pic32_uart_stop_tx(struct uart_port *port) | ||
136 | { | ||
137 | struct pic32_sport *sport = to_pic32_sport(port); | ||
138 | |||
139 | if (!(pic32_uart_readl(sport, PIC32_UART_MODE) & PIC32_UART_MODE_ON)) | ||
140 | return; | ||
141 | |||
142 | if (!(pic32_uart_readl(sport, PIC32_UART_STA) & PIC32_UART_STA_UTXEN)) | ||
143 | return; | ||
144 | |||
145 | /* wait for tx empty */ | ||
146 | pic32_wait_deplete_txbuf(sport); | ||
147 | |||
148 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), | ||
149 | PIC32_UART_STA_UTXEN); | ||
150 | pic32_uart_irqtxen(sport, 0); | ||
151 | } | ||
152 | |||
153 | /* serial core request to (re)enable tx */ | ||
154 | static void pic32_uart_start_tx(struct uart_port *port) | ||
155 | { | ||
156 | struct pic32_sport *sport = to_pic32_sport(port); | ||
157 | |||
158 | pic32_uart_irqtxen(sport, 1); | ||
159 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA), | ||
160 | PIC32_UART_STA_UTXEN); | ||
161 | } | ||
162 | |||
163 | /* serial core request to stop rx, called before port shutdown */ | ||
164 | static void pic32_uart_stop_rx(struct uart_port *port) | ||
165 | { | ||
166 | struct pic32_sport *sport = to_pic32_sport(port); | ||
167 | |||
168 | /* disable rx interrupts */ | ||
169 | disable_irq(sport->irq_rx); | ||
170 | |||
171 | /* receiver Enable bit OFF */ | ||
172 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), | ||
173 | PIC32_UART_STA_URXEN); | ||
174 | } | ||
175 | |||
176 | /* serial core request to start/stop emitting break char */ | ||
177 | static void pic32_uart_break_ctl(struct uart_port *port, int ctl) | ||
178 | { | ||
179 | struct pic32_sport *sport = to_pic32_sport(port); | ||
180 | unsigned long flags; | ||
181 | |||
182 | spin_lock_irqsave(&port->lock, flags); | ||
183 | |||
184 | if (ctl) | ||
185 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA), | ||
186 | PIC32_UART_STA_UTXBRK); | ||
187 | else | ||
188 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), | ||
189 | PIC32_UART_STA_UTXBRK); | ||
190 | |||
191 | spin_unlock_irqrestore(&port->lock, flags); | ||
192 | } | ||
193 | |||
194 | /* get port type in string format */ | ||
195 | static const char *pic32_uart_type(struct uart_port *port) | ||
196 | { | ||
197 | return (port->type == PORT_PIC32) ? PIC32_DEV_NAME : NULL; | ||
198 | } | ||
199 | |||
200 | /* read all chars in rx fifo and send them to core */ | ||
201 | static void pic32_uart_do_rx(struct uart_port *port) | ||
202 | { | ||
203 | struct pic32_sport *sport = to_pic32_sport(port); | ||
204 | struct tty_port *tty; | ||
205 | unsigned int max_count; | ||
206 | |||
207 | /* limit number of char read in interrupt, should not be | ||
208 | * higher than fifo size anyway since we're much faster than | ||
209 | * serial port | ||
210 | */ | ||
211 | max_count = PIC32_UART_RX_FIFO_DEPTH; | ||
212 | |||
213 | spin_lock(&port->lock); | ||
214 | |||
215 | tty = &port->state->port; | ||
216 | |||
217 | do { | ||
218 | u32 sta_reg, c; | ||
219 | char flag; | ||
220 | |||
221 | /* get overrun/fifo empty information from status register */ | ||
222 | sta_reg = pic32_uart_readl(sport, PIC32_UART_STA); | ||
223 | if (unlikely(sta_reg & PIC32_UART_STA_OERR)) { | ||
224 | |||
225 | /* fifo reset is required to clear interrupt */ | ||
226 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), | ||
227 | PIC32_UART_STA_OERR); | ||
228 | |||
229 | port->icount.overrun++; | ||
230 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
231 | } | ||
232 | |||
233 | /* Can at least one more character can be read? */ | ||
234 | if (!(sta_reg & PIC32_UART_STA_URXDA)) | ||
235 | break; | ||
236 | |||
237 | /* read the character and increment the rx counter */ | ||
238 | c = pic32_uart_readl(sport, PIC32_UART_RX); | ||
239 | |||
240 | port->icount.rx++; | ||
241 | flag = TTY_NORMAL; | ||
242 | c &= 0xff; | ||
243 | |||
244 | if (unlikely((sta_reg & PIC32_UART_STA_PERR) || | ||
245 | (sta_reg & PIC32_UART_STA_FERR))) { | ||
246 | |||
247 | /* do stats first */ | ||
248 | if (sta_reg & PIC32_UART_STA_PERR) | ||
249 | port->icount.parity++; | ||
250 | if (sta_reg & PIC32_UART_STA_FERR) | ||
251 | port->icount.frame++; | ||
252 | |||
253 | /* update flag wrt read_status_mask */ | ||
254 | sta_reg &= port->read_status_mask; | ||
255 | |||
256 | if (sta_reg & PIC32_UART_STA_FERR) | ||
257 | flag = TTY_FRAME; | ||
258 | if (sta_reg & PIC32_UART_STA_PERR) | ||
259 | flag = TTY_PARITY; | ||
260 | } | ||
261 | |||
262 | if (uart_handle_sysrq_char(port, c)) | ||
263 | continue; | ||
264 | |||
265 | if ((sta_reg & port->ignore_status_mask) == 0) | ||
266 | tty_insert_flip_char(tty, c, flag); | ||
267 | |||
268 | } while (--max_count); | ||
269 | |||
270 | spin_unlock(&port->lock); | ||
271 | |||
272 | tty_flip_buffer_push(tty); | ||
273 | } | ||
274 | |||
275 | /* fill tx fifo with chars to send, stop when fifo is about to be full | ||
276 | * or when all chars have been sent. | ||
277 | */ | ||
278 | static void pic32_uart_do_tx(struct uart_port *port) | ||
279 | { | ||
280 | struct pic32_sport *sport = to_pic32_sport(port); | ||
281 | struct circ_buf *xmit = &port->state->xmit; | ||
282 | unsigned int max_count = PIC32_UART_TX_FIFO_DEPTH; | ||
283 | |||
284 | if (port->x_char) { | ||
285 | pic32_uart_writel(sport, PIC32_UART_TX, port->x_char); | ||
286 | port->icount.tx++; | ||
287 | port->x_char = 0; | ||
288 | return; | ||
289 | } | ||
290 | |||
291 | if (uart_tx_stopped(port)) { | ||
292 | pic32_uart_stop_tx(port); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | if (uart_circ_empty(xmit)) | ||
297 | goto txq_empty; | ||
298 | |||
299 | /* keep stuffing chars into uart tx buffer | ||
300 | * 1) until uart fifo is full | ||
301 | * or | ||
302 | * 2) until the circ buffer is empty | ||
303 | * (all chars have been sent) | ||
304 | * or | ||
305 | * 3) until the max count is reached | ||
306 | * (prevents lingering here for too long in certain cases) | ||
307 | */ | ||
308 | while (!(PIC32_UART_STA_UTXBF & | ||
309 | pic32_uart_readl(sport, PIC32_UART_STA))) { | ||
310 | unsigned int c = xmit->buf[xmit->tail]; | ||
311 | |||
312 | pic32_uart_writel(sport, PIC32_UART_TX, c); | ||
313 | |||
314 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
315 | port->icount.tx++; | ||
316 | if (uart_circ_empty(xmit)) | ||
317 | break; | ||
318 | if (--max_count == 0) | ||
319 | break; | ||
320 | } | ||
321 | |||
322 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
323 | uart_write_wakeup(port); | ||
324 | |||
325 | if (uart_circ_empty(xmit)) | ||
326 | goto txq_empty; | ||
327 | |||
328 | return; | ||
329 | |||
330 | txq_empty: | ||
331 | pic32_uart_irqtxen(sport, 0); | ||
332 | } | ||
333 | |||
334 | /* RX interrupt handler */ | ||
335 | static irqreturn_t pic32_uart_rx_interrupt(int irq, void *dev_id) | ||
336 | { | ||
337 | struct uart_port *port = dev_id; | ||
338 | |||
339 | pic32_uart_do_rx(port); | ||
340 | |||
341 | return IRQ_HANDLED; | ||
342 | } | ||
343 | |||
344 | /* TX interrupt handler */ | ||
345 | static irqreturn_t pic32_uart_tx_interrupt(int irq, void *dev_id) | ||
346 | { | ||
347 | struct uart_port *port = dev_id; | ||
348 | unsigned long flags; | ||
349 | |||
350 | spin_lock_irqsave(&port->lock, flags); | ||
351 | pic32_uart_do_tx(port); | ||
352 | spin_unlock_irqrestore(&port->lock, flags); | ||
353 | |||
354 | return IRQ_HANDLED; | ||
355 | } | ||
356 | |||
357 | /* FAULT interrupt handler */ | ||
358 | static irqreturn_t pic32_uart_fault_interrupt(int irq, void *dev_id) | ||
359 | { | ||
360 | /* do nothing: pic32_uart_do_rx() handles faults. */ | ||
361 | return IRQ_HANDLED; | ||
362 | } | ||
363 | |||
364 | /* enable rx & tx operation on uart */ | ||
365 | static void pic32_uart_en_and_unmask(struct uart_port *port) | ||
366 | { | ||
367 | struct pic32_sport *sport = to_pic32_sport(port); | ||
368 | |||
369 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA), | ||
370 | PIC32_UART_STA_UTXEN | PIC32_UART_STA_URXEN); | ||
371 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE), | ||
372 | PIC32_UART_MODE_ON); | ||
373 | } | ||
374 | |||
375 | /* disable rx & tx operation on uart */ | ||
376 | static void pic32_uart_dsbl_and_mask(struct uart_port *port) | ||
377 | { | ||
378 | struct pic32_sport *sport = to_pic32_sport(port); | ||
379 | |||
380 | /* wait for tx empty, otherwise chars will be lost or corrupted */ | ||
381 | pic32_wait_deplete_txbuf(sport); | ||
382 | |||
383 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), | ||
384 | PIC32_UART_STA_UTXEN | PIC32_UART_STA_URXEN); | ||
385 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
386 | PIC32_UART_MODE_ON); | ||
387 | } | ||
388 | |||
389 | /* serial core request to initialize uart and start rx operation */ | ||
390 | static int pic32_uart_startup(struct uart_port *port) | ||
391 | { | ||
392 | struct pic32_sport *sport = to_pic32_sport(port); | ||
393 | u32 dflt_baud = (port->uartclk / PIC32_UART_DFLT_BRATE / 16) - 1; | ||
394 | unsigned long flags; | ||
395 | int ret; | ||
396 | |||
397 | local_irq_save(flags); | ||
398 | |||
399 | ret = pic32_enable_clock(sport); | ||
400 | if (ret) { | ||
401 | local_irq_restore(flags); | ||
402 | goto out_done; | ||
403 | } | ||
404 | |||
405 | /* clear status and mode registers */ | ||
406 | pic32_uart_writel(sport, PIC32_UART_MODE, 0); | ||
407 | pic32_uart_writel(sport, PIC32_UART_STA, 0); | ||
408 | |||
409 | /* disable uart and mask all interrupts */ | ||
410 | pic32_uart_dsbl_and_mask(port); | ||
411 | |||
412 | /* set default baud */ | ||
413 | pic32_uart_writel(sport, PIC32_UART_BRG, dflt_baud); | ||
414 | |||
415 | local_irq_restore(flags); | ||
416 | |||
417 | /* Each UART of a PIC32 has three interrupts therefore, | ||
418 | * we setup driver to register the 3 irqs for the device. | ||
419 | * | ||
420 | * For each irq request_irq() is called with interrupt disabled. | ||
421 | * And the irq is enabled as soon as we are ready to handle them. | ||
422 | */ | ||
423 | tx_irq_enabled(sport) = 0; | ||
424 | |||
425 | sport->irq_fault_name = kasprintf(GFP_KERNEL, "%s%d-fault", | ||
426 | pic32_uart_type(port), | ||
427 | sport->idx); | ||
428 | if (!sport->irq_fault_name) { | ||
429 | dev_err(port->dev, "%s: kasprintf err!", __func__); | ||
430 | ret = -ENOMEM; | ||
431 | goto out_done; | ||
432 | } | ||
433 | irq_set_status_flags(sport->irq_fault, IRQ_NOAUTOEN); | ||
434 | ret = request_irq(sport->irq_fault, pic32_uart_fault_interrupt, | ||
435 | sport->irqflags_fault, sport->irq_fault_name, port); | ||
436 | if (ret) { | ||
437 | dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n", | ||
438 | __func__, sport->irq_fault, ret, | ||
439 | pic32_uart_type(port)); | ||
440 | goto out_f; | ||
441 | } | ||
442 | |||
443 | sport->irq_rx_name = kasprintf(GFP_KERNEL, "%s%d-rx", | ||
444 | pic32_uart_type(port), | ||
445 | sport->idx); | ||
446 | if (!sport->irq_rx_name) { | ||
447 | dev_err(port->dev, "%s: kasprintf err!", __func__); | ||
448 | kfree(sport->irq_fault_name); | ||
449 | ret = -ENOMEM; | ||
450 | goto out_f; | ||
451 | } | ||
452 | irq_set_status_flags(sport->irq_rx, IRQ_NOAUTOEN); | ||
453 | ret = request_irq(sport->irq_rx, pic32_uart_rx_interrupt, | ||
454 | sport->irqflags_rx, sport->irq_rx_name, port); | ||
455 | if (ret) { | ||
456 | dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n", | ||
457 | __func__, sport->irq_rx, ret, | ||
458 | pic32_uart_type(port)); | ||
459 | goto out_r; | ||
460 | } | ||
461 | |||
462 | sport->irq_tx_name = kasprintf(GFP_KERNEL, "%s%d-tx", | ||
463 | pic32_uart_type(port), | ||
464 | sport->idx); | ||
465 | if (!sport->irq_tx_name) { | ||
466 | dev_err(port->dev, "%s: kasprintf err!", __func__); | ||
467 | ret = -ENOMEM; | ||
468 | goto out_r; | ||
469 | } | ||
470 | irq_set_status_flags(sport->irq_tx, IRQ_NOAUTOEN); | ||
471 | ret = request_irq(sport->irq_tx, pic32_uart_tx_interrupt, | ||
472 | sport->irqflags_tx, sport->irq_tx_name, port); | ||
473 | if (ret) { | ||
474 | dev_err(port->dev, "%s: request irq(%d) err! ret:%d name:%s\n", | ||
475 | __func__, sport->irq_tx, ret, | ||
476 | pic32_uart_type(port)); | ||
477 | goto out_t; | ||
478 | } | ||
479 | |||
480 | local_irq_save(flags); | ||
481 | |||
482 | /* set rx interrupt on first receive */ | ||
483 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), | ||
484 | PIC32_UART_STA_URXISEL1 | PIC32_UART_STA_URXISEL0); | ||
485 | |||
486 | /* set interrupt on empty */ | ||
487 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), | ||
488 | PIC32_UART_STA_UTXISEL1); | ||
489 | |||
490 | /* enable all interrupts and eanable uart */ | ||
491 | pic32_uart_en_and_unmask(port); | ||
492 | |||
493 | enable_irq(sport->irq_rx); | ||
494 | |||
495 | return 0; | ||
496 | |||
497 | out_t: | ||
498 | kfree(sport->irq_tx_name); | ||
499 | free_irq(sport->irq_tx, sport); | ||
500 | out_r: | ||
501 | kfree(sport->irq_rx_name); | ||
502 | free_irq(sport->irq_rx, sport); | ||
503 | out_f: | ||
504 | kfree(sport->irq_fault_name); | ||
505 | free_irq(sport->irq_fault, sport); | ||
506 | out_done: | ||
507 | return ret; | ||
508 | } | ||
509 | |||
510 | /* serial core request to flush & disable uart */ | ||
511 | static void pic32_uart_shutdown(struct uart_port *port) | ||
512 | { | ||
513 | struct pic32_sport *sport = to_pic32_sport(port); | ||
514 | unsigned long flags; | ||
515 | |||
516 | /* disable uart */ | ||
517 | spin_lock_irqsave(&port->lock, flags); | ||
518 | pic32_uart_dsbl_and_mask(port); | ||
519 | spin_unlock_irqrestore(&port->lock, flags); | ||
520 | pic32_disable_clock(sport); | ||
521 | |||
522 | /* free all 3 interrupts for this UART */ | ||
523 | free_irq(sport->irq_fault, port); | ||
524 | free_irq(sport->irq_tx, port); | ||
525 | free_irq(sport->irq_rx, port); | ||
526 | } | ||
527 | |||
528 | /* serial core request to change current uart setting */ | ||
529 | static void pic32_uart_set_termios(struct uart_port *port, | ||
530 | struct ktermios *new, | ||
531 | struct ktermios *old) | ||
532 | { | ||
533 | struct pic32_sport *sport = to_pic32_sport(port); | ||
534 | unsigned int baud; | ||
535 | unsigned int quot; | ||
536 | unsigned long flags; | ||
537 | |||
538 | spin_lock_irqsave(&port->lock, flags); | ||
539 | |||
540 | /* disable uart and mask all interrupts while changing speed */ | ||
541 | pic32_uart_dsbl_and_mask(port); | ||
542 | |||
543 | /* stop bit options */ | ||
544 | if (new->c_cflag & CSTOPB) | ||
545 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE), | ||
546 | PIC32_UART_MODE_STSEL); | ||
547 | else | ||
548 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
549 | PIC32_UART_MODE_STSEL); | ||
550 | |||
551 | /* parity options */ | ||
552 | if (new->c_cflag & PARENB) { | ||
553 | if (new->c_cflag & PARODD) { | ||
554 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE), | ||
555 | PIC32_UART_MODE_PDSEL1); | ||
556 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
557 | PIC32_UART_MODE_PDSEL0); | ||
558 | } else { | ||
559 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE), | ||
560 | PIC32_UART_MODE_PDSEL0); | ||
561 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
562 | PIC32_UART_MODE_PDSEL1); | ||
563 | } | ||
564 | } else { | ||
565 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
566 | PIC32_UART_MODE_PDSEL1 | | ||
567 | PIC32_UART_MODE_PDSEL0); | ||
568 | } | ||
569 | /* if hw flow ctrl, then the pins must be specified in device tree */ | ||
570 | if ((new->c_cflag & CRTSCTS) && sport->hw_flow_ctrl) { | ||
571 | /* enable hardware flow control */ | ||
572 | pic32_uart_writel(sport, PIC32_SET(PIC32_UART_MODE), | ||
573 | PIC32_UART_MODE_UEN1); | ||
574 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
575 | PIC32_UART_MODE_UEN0); | ||
576 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
577 | PIC32_UART_MODE_RTSMD); | ||
578 | } else { | ||
579 | /* disable hardware flow control */ | ||
580 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
581 | PIC32_UART_MODE_UEN1); | ||
582 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
583 | PIC32_UART_MODE_UEN0); | ||
584 | pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_MODE), | ||
585 | PIC32_UART_MODE_RTSMD); | ||
586 | } | ||
587 | |||
588 | /* Always 8-bit */ | ||
589 | new->c_cflag |= CS8; | ||
590 | |||
591 | /* Mark/Space parity is not supported */ | ||
592 | new->c_cflag &= ~CMSPAR; | ||
593 | |||
594 | /* update baud */ | ||
595 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | ||
596 | quot = uart_get_divisor(port, baud) - 1; | ||
597 | pic32_uart_writel(sport, PIC32_UART_BRG, quot); | ||
598 | uart_update_timeout(port, new->c_cflag, baud); | ||
599 | |||
600 | if (tty_termios_baud_rate(new)) | ||
601 | tty_termios_encode_baud_rate(new, baud, baud); | ||
602 | |||
603 | /* enable uart */ | ||
604 | pic32_uart_en_and_unmask(port); | ||
605 | |||
606 | spin_unlock_irqrestore(&port->lock, flags); | ||
607 | } | ||
608 | |||
609 | /* serial core request to claim uart iomem */ | ||
610 | static int pic32_uart_request_port(struct uart_port *port) | ||
611 | { | ||
612 | struct platform_device *pdev = to_platform_device(port->dev); | ||
613 | struct resource *res_mem; | ||
614 | |||
615 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
616 | if (unlikely(!res_mem)) | ||
617 | return -EINVAL; | ||
618 | |||
619 | if (!request_mem_region(port->mapbase, resource_size(res_mem), | ||
620 | "pic32_uart_mem")) | ||
621 | return -EBUSY; | ||
622 | |||
623 | port->membase = devm_ioremap_nocache(port->dev, port->mapbase, | ||
624 | resource_size(res_mem)); | ||
625 | if (!port->membase) { | ||
626 | dev_err(port->dev, "Unable to map registers\n"); | ||
627 | release_mem_region(port->mapbase, resource_size(res_mem)); | ||
628 | return -ENOMEM; | ||
629 | } | ||
630 | |||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | /* serial core request to release uart iomem */ | ||
635 | static void pic32_uart_release_port(struct uart_port *port) | ||
636 | { | ||
637 | struct platform_device *pdev = to_platform_device(port->dev); | ||
638 | struct resource *res_mem; | ||
639 | unsigned int res_size; | ||
640 | |||
641 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
642 | if (unlikely(!res_mem)) | ||
643 | return; | ||
644 | res_size = resource_size(res_mem); | ||
645 | |||
646 | release_mem_region(port->mapbase, res_size); | ||
647 | } | ||
648 | |||
649 | /* serial core request to do any port required auto-configuration */ | ||
650 | static void pic32_uart_config_port(struct uart_port *port, int flags) | ||
651 | { | ||
652 | if (flags & UART_CONFIG_TYPE) { | ||
653 | if (pic32_uart_request_port(port)) | ||
654 | return; | ||
655 | port->type = PORT_PIC32; | ||
656 | } | ||
657 | } | ||
658 | |||
659 | /* serial core request to check that port information in serinfo are suitable */ | ||
660 | static int pic32_uart_verify_port(struct uart_port *port, | ||
661 | struct serial_struct *serinfo) | ||
662 | { | ||
663 | if (port->type != PORT_PIC32) | ||
664 | return -EINVAL; | ||
665 | if (port->irq != serinfo->irq) | ||
666 | return -EINVAL; | ||
667 | if (port->iotype != serinfo->io_type) | ||
668 | return -EINVAL; | ||
669 | if (port->mapbase != (unsigned long)serinfo->iomem_base) | ||
670 | return -EINVAL; | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | /* serial core callbacks */ | ||
676 | static const struct uart_ops pic32_uart_ops = { | ||
677 | .tx_empty = pic32_uart_tx_empty, | ||
678 | .get_mctrl = pic32_uart_get_mctrl, | ||
679 | .set_mctrl = pic32_uart_set_mctrl, | ||
680 | .start_tx = pic32_uart_start_tx, | ||
681 | .stop_tx = pic32_uart_stop_tx, | ||
682 | .stop_rx = pic32_uart_stop_rx, | ||
683 | .break_ctl = pic32_uart_break_ctl, | ||
684 | .startup = pic32_uart_startup, | ||
685 | .shutdown = pic32_uart_shutdown, | ||
686 | .set_termios = pic32_uart_set_termios, | ||
687 | .type = pic32_uart_type, | ||
688 | .release_port = pic32_uart_release_port, | ||
689 | .request_port = pic32_uart_request_port, | ||
690 | .config_port = pic32_uart_config_port, | ||
691 | .verify_port = pic32_uart_verify_port, | ||
692 | }; | ||
693 | |||
694 | #ifdef CONFIG_SERIAL_PIC32_CONSOLE | ||
695 | /* output given char */ | ||
696 | static void pic32_console_putchar(struct uart_port *port, int ch) | ||
697 | { | ||
698 | struct pic32_sport *sport = to_pic32_sport(port); | ||
699 | |||
700 | if (!(pic32_uart_readl(sport, PIC32_UART_MODE) & PIC32_UART_MODE_ON)) | ||
701 | return; | ||
702 | |||
703 | if (!(pic32_uart_readl(sport, PIC32_UART_STA) & PIC32_UART_STA_UTXEN)) | ||
704 | return; | ||
705 | |||
706 | /* wait for tx empty */ | ||
707 | pic32_wait_deplete_txbuf(sport); | ||
708 | |||
709 | pic32_uart_writel(sport, PIC32_UART_TX, ch & 0xff); | ||
710 | } | ||
711 | |||
712 | /* console core request to output given string */ | ||
713 | static void pic32_console_write(struct console *co, const char *s, | ||
714 | unsigned int count) | ||
715 | { | ||
716 | struct pic32_sport *sport = pic32_sports[co->index]; | ||
717 | struct uart_port *port = pic32_get_port(sport); | ||
718 | |||
719 | /* call uart helper to deal with \r\n */ | ||
720 | uart_console_write(port, s, count, pic32_console_putchar); | ||
721 | } | ||
722 | |||
723 | /* console core request to setup given console, find matching uart | ||
724 | * port and setup it. | ||
725 | */ | ||
726 | static int pic32_console_setup(struct console *co, char *options) | ||
727 | { | ||
728 | struct pic32_sport *sport; | ||
729 | struct uart_port *port = NULL; | ||
730 | int baud = 115200; | ||
731 | int bits = 8; | ||
732 | int parity = 'n'; | ||
733 | int flow = 'n'; | ||
734 | int ret = 0; | ||
735 | |||
736 | if (unlikely(co->index < 0 || co->index >= PIC32_MAX_UARTS)) | ||
737 | return -ENODEV; | ||
738 | |||
739 | sport = pic32_sports[co->index]; | ||
740 | if (!sport) | ||
741 | return -ENODEV; | ||
742 | port = pic32_get_port(sport); | ||
743 | |||
744 | ret = pic32_enable_clock(sport); | ||
745 | if (ret) | ||
746 | return ret; | ||
747 | |||
748 | if (options) | ||
749 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
750 | |||
751 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
752 | } | ||
753 | |||
754 | static struct uart_driver pic32_uart_driver; | ||
755 | static struct console pic32_console = { | ||
756 | .name = PIC32_SDEV_NAME, | ||
757 | .write = pic32_console_write, | ||
758 | .device = uart_console_device, | ||
759 | .setup = pic32_console_setup, | ||
760 | .flags = CON_PRINTBUFFER, | ||
761 | .index = -1, | ||
762 | .data = &pic32_uart_driver, | ||
763 | }; | ||
764 | #define PIC32_SCONSOLE (&pic32_console) | ||
765 | |||
766 | static int __init pic32_console_init(void) | ||
767 | { | ||
768 | register_console(&pic32_console); | ||
769 | return 0; | ||
770 | } | ||
771 | console_initcall(pic32_console_init); | ||
772 | |||
773 | static inline bool is_pic32_console_port(struct uart_port *port) | ||
774 | { | ||
775 | return port->cons && port->cons->index == port->line; | ||
776 | } | ||
777 | |||
778 | /* | ||
779 | * Late console initialization. | ||
780 | */ | ||
781 | static int __init pic32_late_console_init(void) | ||
782 | { | ||
783 | if (!(pic32_console.flags & CON_ENABLED)) | ||
784 | register_console(&pic32_console); | ||
785 | |||
786 | return 0; | ||
787 | } | ||
788 | |||
789 | core_initcall(pic32_late_console_init); | ||
790 | |||
791 | #else | ||
792 | #define PIC32_SCONSOLE NULL | ||
793 | #endif | ||
794 | |||
795 | static struct uart_driver pic32_uart_driver = { | ||
796 | .owner = THIS_MODULE, | ||
797 | .driver_name = PIC32_DEV_NAME, | ||
798 | .dev_name = PIC32_SDEV_NAME, | ||
799 | .nr = PIC32_MAX_UARTS, | ||
800 | .cons = PIC32_SCONSOLE, | ||
801 | }; | ||
802 | |||
803 | static int pic32_uart_probe(struct platform_device *pdev) | ||
804 | { | ||
805 | struct device_node *np = pdev->dev.of_node; | ||
806 | struct pic32_sport *sport; | ||
807 | int uart_idx = 0; | ||
808 | struct resource *res_mem; | ||
809 | struct uart_port *port; | ||
810 | int ret; | ||
811 | |||
812 | uart_idx = of_alias_get_id(np, "serial"); | ||
813 | if (uart_idx < 0 || uart_idx >= PIC32_MAX_UARTS) | ||
814 | return -EINVAL; | ||
815 | |||
816 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
817 | if (!res_mem) | ||
818 | return -EINVAL; | ||
819 | |||
820 | sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); | ||
821 | if (!sport) | ||
822 | return -ENOMEM; | ||
823 | |||
824 | sport->idx = uart_idx; | ||
825 | sport->irq_fault = irq_of_parse_and_map(np, 0); | ||
826 | sport->irqflags_fault = IRQF_NO_THREAD; | ||
827 | sport->irq_rx = irq_of_parse_and_map(np, 1); | ||
828 | sport->irqflags_rx = IRQF_NO_THREAD; | ||
829 | sport->irq_tx = irq_of_parse_and_map(np, 2); | ||
830 | sport->irqflags_tx = IRQF_NO_THREAD; | ||
831 | sport->clk = devm_clk_get(&pdev->dev, NULL); | ||
832 | sport->cts_gpio = -EINVAL; | ||
833 | sport->dev = &pdev->dev; | ||
834 | |||
835 | /* Hardware flow control: gpios | ||
836 | * !Note: Basically, CTS is needed for reading the status. | ||
837 | */ | ||
838 | sport->hw_flow_ctrl = false; | ||
839 | sport->cts_gpio = of_get_named_gpio(np, "cts-gpios", 0); | ||
840 | if (gpio_is_valid(sport->cts_gpio)) { | ||
841 | sport->hw_flow_ctrl = true; | ||
842 | |||
843 | ret = devm_gpio_request(sport->dev, | ||
844 | sport->cts_gpio, "CTS"); | ||
845 | if (ret) { | ||
846 | dev_err(&pdev->dev, | ||
847 | "error requesting CTS GPIO\n"); | ||
848 | goto err; | ||
849 | } | ||
850 | |||
851 | ret = gpio_direction_input(sport->cts_gpio); | ||
852 | if (ret) { | ||
853 | dev_err(&pdev->dev, "error setting CTS GPIO\n"); | ||
854 | goto err; | ||
855 | } | ||
856 | } | ||
857 | |||
858 | pic32_sports[uart_idx] = sport; | ||
859 | port = &sport->port; | ||
860 | memset(port, 0, sizeof(*port)); | ||
861 | port->iotype = UPIO_MEM; | ||
862 | port->mapbase = res_mem->start; | ||
863 | port->ops = &pic32_uart_ops; | ||
864 | port->flags = UPF_BOOT_AUTOCONF; | ||
865 | port->dev = &pdev->dev; | ||
866 | port->fifosize = PIC32_UART_TX_FIFO_DEPTH; | ||
867 | port->uartclk = clk_get_rate(sport->clk); | ||
868 | port->line = uart_idx; | ||
869 | |||
870 | ret = uart_add_one_port(&pic32_uart_driver, port); | ||
871 | if (ret) { | ||
872 | port->membase = NULL; | ||
873 | dev_err(port->dev, "%s: uart add port error!\n", __func__); | ||
874 | goto err; | ||
875 | } | ||
876 | |||
877 | #ifdef CONFIG_SERIAL_PIC32_CONSOLE | ||
878 | if (is_pic32_console_port(port) && | ||
879 | (pic32_console.flags & CON_ENABLED)) { | ||
880 | /* The peripheral clock has been enabled by console_setup, | ||
881 | * so disable it till the port is used. | ||
882 | */ | ||
883 | pic32_disable_clock(sport); | ||
884 | } | ||
885 | #endif | ||
886 | |||
887 | platform_set_drvdata(pdev, port); | ||
888 | |||
889 | dev_info(&pdev->dev, "%s: uart(%d) driver initialized.\n", | ||
890 | __func__, uart_idx); | ||
891 | |||
892 | return 0; | ||
893 | err: | ||
894 | /* automatic unroll of sport and gpios */ | ||
895 | return ret; | ||
896 | } | ||
897 | |||
898 | static int pic32_uart_remove(struct platform_device *pdev) | ||
899 | { | ||
900 | struct uart_port *port = platform_get_drvdata(pdev); | ||
901 | struct pic32_sport *sport = to_pic32_sport(port); | ||
902 | |||
903 | uart_remove_one_port(&pic32_uart_driver, port); | ||
904 | pic32_disable_clock(sport); | ||
905 | platform_set_drvdata(pdev, NULL); | ||
906 | pic32_sports[sport->idx] = NULL; | ||
907 | |||
908 | /* automatic unroll of sport and gpios */ | ||
909 | return 0; | ||
910 | } | ||
911 | |||
912 | static const struct of_device_id pic32_serial_dt_ids[] = { | ||
913 | { .compatible = "microchip,pic32mzda-uart" }, | ||
914 | { /* sentinel */ } | ||
915 | }; | ||
916 | MODULE_DEVICE_TABLE(of, pic32_serial_dt_ids); | ||
917 | |||
918 | static struct platform_driver pic32_uart_platform_driver = { | ||
919 | .probe = pic32_uart_probe, | ||
920 | .remove = pic32_uart_remove, | ||
921 | .driver = { | ||
922 | .name = PIC32_DEV_NAME, | ||
923 | .of_match_table = of_match_ptr(pic32_serial_dt_ids), | ||
924 | }, | ||
925 | }; | ||
926 | |||
927 | static int __init pic32_uart_init(void) | ||
928 | { | ||
929 | int ret; | ||
930 | |||
931 | ret = uart_register_driver(&pic32_uart_driver); | ||
932 | if (ret) { | ||
933 | pr_err("failed to register %s:%d\n", | ||
934 | pic32_uart_driver.driver_name, ret); | ||
935 | return ret; | ||
936 | } | ||
937 | |||
938 | ret = platform_driver_register(&pic32_uart_platform_driver); | ||
939 | if (ret) { | ||
940 | pr_err("fail to register pic32 uart\n"); | ||
941 | uart_unregister_driver(&pic32_uart_driver); | ||
942 | } | ||
943 | |||
944 | return ret; | ||
945 | } | ||
946 | arch_initcall(pic32_uart_init); | ||
947 | |||
948 | static void __exit pic32_uart_exit(void) | ||
949 | { | ||
950 | #ifdef CONFIG_SERIAL_PIC32_CONSOLE | ||
951 | unregister_console(&pic32_console); | ||
952 | #endif | ||
953 | platform_driver_unregister(&pic32_uart_platform_driver); | ||
954 | uart_unregister_driver(&pic32_uart_driver); | ||
955 | } | ||
956 | module_exit(pic32_uart_exit); | ||
957 | |||
958 | MODULE_AUTHOR("Sorin-Andrei Pistirica <andrei.pistirica@microchip.com>"); | ||
959 | MODULE_DESCRIPTION("Microchip PIC32 integrated serial port driver"); | ||
960 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/pic32_uart.h b/drivers/tty/serial/pic32_uart.h new file mode 100644 index 000000000000..ec379da55ebb --- /dev/null +++ b/drivers/tty/serial/pic32_uart.h | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * PIC32 Integrated Serial Driver. | ||
3 | * | ||
4 | * Copyright (C) 2015 Microchip Technology, Inc. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Sorin-Andrei Pistirica <andrei.pistirica@microchip.com> | ||
8 | * | ||
9 | * Licensed under GPLv2 or later. | ||
10 | */ | ||
11 | #ifndef __DT_PIC32_UART_H__ | ||
12 | #define __DT_PIC32_UART_H__ | ||
13 | |||
14 | #define PIC32_UART_DFLT_BRATE (9600) | ||
15 | #define PIC32_UART_TX_FIFO_DEPTH (8) | ||
16 | #define PIC32_UART_RX_FIFO_DEPTH (8) | ||
17 | |||
18 | #define PIC32_UART_MODE 0x00 | ||
19 | #define PIC32_UART_STA 0x10 | ||
20 | #define PIC32_UART_TX 0x20 | ||
21 | #define PIC32_UART_RX 0x30 | ||
22 | #define PIC32_UART_BRG 0x40 | ||
23 | |||
24 | struct pic32_console_opt { | ||
25 | int baud; | ||
26 | int parity; | ||
27 | int bits; | ||
28 | int flow; | ||
29 | }; | ||
30 | |||
31 | /* struct pic32_sport - pic32 serial port descriptor | ||
32 | * @port: uart port descriptor | ||
33 | * @idx: port index | ||
34 | * @irq_fault: virtual fault interrupt number | ||
35 | * @irqflags_fault: flags related to fault irq | ||
36 | * @irq_fault_name: irq fault name | ||
37 | * @irq_rx: virtual rx interrupt number | ||
38 | * @irqflags_rx: flags related to rx irq | ||
39 | * @irq_rx_name: irq rx name | ||
40 | * @irq_tx: virtual tx interrupt number | ||
41 | * @irqflags_tx: : flags related to tx irq | ||
42 | * @irq_tx_name: irq tx name | ||
43 | * @cts_gpio: clear to send gpio | ||
44 | * @dev: device descriptor | ||
45 | **/ | ||
46 | struct pic32_sport { | ||
47 | struct uart_port port; | ||
48 | struct pic32_console_opt opt; | ||
49 | int idx; | ||
50 | |||
51 | int irq_fault; | ||
52 | int irqflags_fault; | ||
53 | const char *irq_fault_name; | ||
54 | int irq_rx; | ||
55 | int irqflags_rx; | ||
56 | const char *irq_rx_name; | ||
57 | int irq_tx; | ||
58 | int irqflags_tx; | ||
59 | const char *irq_tx_name; | ||
60 | u8 enable_tx_irq; | ||
61 | |||
62 | bool hw_flow_ctrl; | ||
63 | int cts_gpio; | ||
64 | |||
65 | int ref_clk; | ||
66 | struct clk *clk; | ||
67 | |||
68 | struct device *dev; | ||
69 | }; | ||
70 | #define to_pic32_sport(c) container_of(c, struct pic32_sport, port) | ||
71 | #define pic32_get_port(sport) (&sport->port) | ||
72 | #define pic32_get_opt(sport) (&sport->opt) | ||
73 | #define tx_irq_enabled(sport) (sport->enable_tx_irq) | ||
74 | |||
75 | static inline void pic32_uart_writel(struct pic32_sport *sport, | ||
76 | u32 reg, u32 val) | ||
77 | { | ||
78 | struct uart_port *port = pic32_get_port(sport); | ||
79 | |||
80 | __raw_writel(val, port->membase + reg); | ||
81 | } | ||
82 | |||
83 | static inline u32 pic32_uart_readl(struct pic32_sport *sport, u32 reg) | ||
84 | { | ||
85 | struct uart_port *port = pic32_get_port(sport); | ||
86 | |||
87 | return __raw_readl(port->membase + reg); | ||
88 | } | ||
89 | |||
90 | /* pic32 uart mode register bits */ | ||
91 | #define PIC32_UART_MODE_ON BIT(15) | ||
92 | #define PIC32_UART_MODE_FRZ BIT(14) | ||
93 | #define PIC32_UART_MODE_SIDL BIT(13) | ||
94 | #define PIC32_UART_MODE_IREN BIT(12) | ||
95 | #define PIC32_UART_MODE_RTSMD BIT(11) | ||
96 | #define PIC32_UART_MODE_RESV1 BIT(10) | ||
97 | #define PIC32_UART_MODE_UEN1 BIT(9) | ||
98 | #define PIC32_UART_MODE_UEN0 BIT(8) | ||
99 | #define PIC32_UART_MODE_WAKE BIT(7) | ||
100 | #define PIC32_UART_MODE_LPBK BIT(6) | ||
101 | #define PIC32_UART_MODE_ABAUD BIT(5) | ||
102 | #define PIC32_UART_MODE_RXINV BIT(4) | ||
103 | #define PIC32_UART_MODE_BRGH BIT(3) | ||
104 | #define PIC32_UART_MODE_PDSEL1 BIT(2) | ||
105 | #define PIC32_UART_MODE_PDSEL0 BIT(1) | ||
106 | #define PIC32_UART_MODE_STSEL BIT(0) | ||
107 | |||
108 | /* pic32 uart status register bits */ | ||
109 | #define PIC32_UART_STA_UTXISEL1 BIT(15) | ||
110 | #define PIC32_UART_STA_UTXISEL0 BIT(14) | ||
111 | #define PIC32_UART_STA_UTXINV BIT(13) | ||
112 | #define PIC32_UART_STA_URXEN BIT(12) | ||
113 | #define PIC32_UART_STA_UTXBRK BIT(11) | ||
114 | #define PIC32_UART_STA_UTXEN BIT(10) | ||
115 | #define PIC32_UART_STA_UTXBF BIT(9) | ||
116 | #define PIC32_UART_STA_TRMT BIT(8) | ||
117 | #define PIC32_UART_STA_URXISEL1 BIT(7) | ||
118 | #define PIC32_UART_STA_URXISEL0 BIT(6) | ||
119 | #define PIC32_UART_STA_ADDEN BIT(5) | ||
120 | #define PIC32_UART_STA_RIDLE BIT(4) | ||
121 | #define PIC32_UART_STA_PERR BIT(3) | ||
122 | #define PIC32_UART_STA_FERR BIT(2) | ||
123 | #define PIC32_UART_STA_OERR BIT(1) | ||
124 | #define PIC32_UART_STA_URXDA BIT(0) | ||
125 | |||
126 | #endif /* __DT_PIC32_UART_H__ */ | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 04dcedfdebf8..0449235d4f22 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -1245,11 +1245,6 @@ MODULE_LICENSE ("GPL"); | |||
1245 | #define TMIO_OHCI_DRIVER ohci_hcd_tmio_driver | 1245 | #define TMIO_OHCI_DRIVER ohci_hcd_tmio_driver |
1246 | #endif | 1246 | #endif |
1247 | 1247 | ||
1248 | #ifdef CONFIG_MACH_JZ4740 | ||
1249 | #include "ohci-jz4740.c" | ||
1250 | #define PLATFORM_DRIVER ohci_hcd_jz4740_driver | ||
1251 | #endif | ||
1252 | |||
1253 | #ifdef CONFIG_TILE_USB | 1248 | #ifdef CONFIG_TILE_USB |
1254 | #include "ohci-tilegx.c" | 1249 | #include "ohci-tilegx.c" |
1255 | #define PLATFORM_DRIVER ohci_hcd_tilegx_driver | 1250 | #define PLATFORM_DRIVER ohci_hcd_tilegx_driver |
diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c deleted file mode 100644 index 4db78f169256..000000000000 --- a/drivers/usb/host/ohci-jz4740.c +++ /dev/null | |||
@@ -1,245 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * You should have received a copy of the GNU General Public License along | ||
10 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
11 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/clk.h> | ||
17 | #include <linux/regulator/consumer.h> | ||
18 | |||
19 | struct jz4740_ohci_hcd { | ||
20 | struct ohci_hcd ohci_hcd; | ||
21 | |||
22 | struct regulator *vbus; | ||
23 | bool vbus_enabled; | ||
24 | struct clk *clk; | ||
25 | }; | ||
26 | |||
27 | static inline struct jz4740_ohci_hcd *hcd_to_jz4740_hcd(struct usb_hcd *hcd) | ||
28 | { | ||
29 | return (struct jz4740_ohci_hcd *)(hcd->hcd_priv); | ||
30 | } | ||
31 | |||
32 | static inline struct usb_hcd *jz4740_hcd_to_hcd(struct jz4740_ohci_hcd *jz4740_ohci) | ||
33 | { | ||
34 | return container_of((void *)jz4740_ohci, struct usb_hcd, hcd_priv); | ||
35 | } | ||
36 | |||
37 | static int ohci_jz4740_start(struct usb_hcd *hcd) | ||
38 | { | ||
39 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
40 | int ret; | ||
41 | |||
42 | ret = ohci_init(ohci); | ||
43 | if (ret < 0) | ||
44 | return ret; | ||
45 | |||
46 | ohci->num_ports = 1; | ||
47 | |||
48 | ret = ohci_run(ohci); | ||
49 | if (ret < 0) { | ||
50 | dev_err(hcd->self.controller, "Can not start %s", | ||
51 | hcd->self.bus_name); | ||
52 | ohci_stop(hcd); | ||
53 | return ret; | ||
54 | } | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static int ohci_jz4740_set_vbus_power(struct jz4740_ohci_hcd *jz4740_ohci, | ||
59 | bool enabled) | ||
60 | { | ||
61 | int ret = 0; | ||
62 | |||
63 | if (!jz4740_ohci->vbus) | ||
64 | return 0; | ||
65 | |||
66 | if (enabled && !jz4740_ohci->vbus_enabled) { | ||
67 | ret = regulator_enable(jz4740_ohci->vbus); | ||
68 | if (ret) | ||
69 | dev_err(jz4740_hcd_to_hcd(jz4740_ohci)->self.controller, | ||
70 | "Could not power vbus\n"); | ||
71 | } else if (!enabled && jz4740_ohci->vbus_enabled) { | ||
72 | ret = regulator_disable(jz4740_ohci->vbus); | ||
73 | } | ||
74 | |||
75 | if (ret == 0) | ||
76 | jz4740_ohci->vbus_enabled = enabled; | ||
77 | |||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | static int ohci_jz4740_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
82 | u16 wIndex, char *buf, u16 wLength) | ||
83 | { | ||
84 | struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd); | ||
85 | int ret = 0; | ||
86 | |||
87 | switch (typeReq) { | ||
88 | case SetPortFeature: | ||
89 | if (wValue == USB_PORT_FEAT_POWER) | ||
90 | ret = ohci_jz4740_set_vbus_power(jz4740_ohci, true); | ||
91 | break; | ||
92 | case ClearPortFeature: | ||
93 | if (wValue == USB_PORT_FEAT_POWER) | ||
94 | ret = ohci_jz4740_set_vbus_power(jz4740_ohci, false); | ||
95 | break; | ||
96 | } | ||
97 | |||
98 | if (ret) | ||
99 | return ret; | ||
100 | |||
101 | return ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); | ||
102 | } | ||
103 | |||
104 | |||
105 | static const struct hc_driver ohci_jz4740_hc_driver = { | ||
106 | .description = hcd_name, | ||
107 | .product_desc = "JZ4740 OHCI", | ||
108 | .hcd_priv_size = sizeof(struct jz4740_ohci_hcd), | ||
109 | |||
110 | /* | ||
111 | * generic hardware linkage | ||
112 | */ | ||
113 | .irq = ohci_irq, | ||
114 | .flags = HCD_USB11 | HCD_MEMORY, | ||
115 | |||
116 | /* | ||
117 | * basic lifecycle operations | ||
118 | */ | ||
119 | .start = ohci_jz4740_start, | ||
120 | .stop = ohci_stop, | ||
121 | .shutdown = ohci_shutdown, | ||
122 | |||
123 | /* | ||
124 | * managing i/o requests and associated device resources | ||
125 | */ | ||
126 | .urb_enqueue = ohci_urb_enqueue, | ||
127 | .urb_dequeue = ohci_urb_dequeue, | ||
128 | .endpoint_disable = ohci_endpoint_disable, | ||
129 | |||
130 | /* | ||
131 | * scheduling support | ||
132 | */ | ||
133 | .get_frame_number = ohci_get_frame, | ||
134 | |||
135 | /* | ||
136 | * root hub support | ||
137 | */ | ||
138 | .hub_status_data = ohci_hub_status_data, | ||
139 | .hub_control = ohci_jz4740_hub_control, | ||
140 | #ifdef CONFIG_PM | ||
141 | .bus_suspend = ohci_bus_suspend, | ||
142 | .bus_resume = ohci_bus_resume, | ||
143 | #endif | ||
144 | .start_port_reset = ohci_start_port_reset, | ||
145 | }; | ||
146 | |||
147 | |||
148 | static int jz4740_ohci_probe(struct platform_device *pdev) | ||
149 | { | ||
150 | int ret; | ||
151 | struct usb_hcd *hcd; | ||
152 | struct jz4740_ohci_hcd *jz4740_ohci; | ||
153 | struct resource *res; | ||
154 | int irq; | ||
155 | |||
156 | irq = platform_get_irq(pdev, 0); | ||
157 | if (irq < 0) { | ||
158 | dev_err(&pdev->dev, "Failed to get platform irq\n"); | ||
159 | return irq; | ||
160 | } | ||
161 | |||
162 | hcd = usb_create_hcd(&ohci_jz4740_hc_driver, &pdev->dev, "jz4740"); | ||
163 | if (!hcd) { | ||
164 | dev_err(&pdev->dev, "Failed to create hcd.\n"); | ||
165 | return -ENOMEM; | ||
166 | } | ||
167 | |||
168 | jz4740_ohci = hcd_to_jz4740_hcd(hcd); | ||
169 | |||
170 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
171 | hcd->regs = devm_ioremap_resource(&pdev->dev, res); | ||
172 | if (IS_ERR(hcd->regs)) { | ||
173 | ret = PTR_ERR(hcd->regs); | ||
174 | goto err_free; | ||
175 | } | ||
176 | hcd->rsrc_start = res->start; | ||
177 | hcd->rsrc_len = resource_size(res); | ||
178 | |||
179 | jz4740_ohci->clk = devm_clk_get(&pdev->dev, "uhc"); | ||
180 | if (IS_ERR(jz4740_ohci->clk)) { | ||
181 | ret = PTR_ERR(jz4740_ohci->clk); | ||
182 | dev_err(&pdev->dev, "Failed to get clock: %d\n", ret); | ||
183 | goto err_free; | ||
184 | } | ||
185 | |||
186 | jz4740_ohci->vbus = devm_regulator_get(&pdev->dev, "vbus"); | ||
187 | if (IS_ERR(jz4740_ohci->vbus)) | ||
188 | jz4740_ohci->vbus = NULL; | ||
189 | |||
190 | |||
191 | clk_set_rate(jz4740_ohci->clk, 48000000); | ||
192 | clk_enable(jz4740_ohci->clk); | ||
193 | if (jz4740_ohci->vbus) | ||
194 | ohci_jz4740_set_vbus_power(jz4740_ohci, true); | ||
195 | |||
196 | platform_set_drvdata(pdev, hcd); | ||
197 | |||
198 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
199 | |||
200 | ret = usb_add_hcd(hcd, irq, 0); | ||
201 | if (ret) { | ||
202 | dev_err(&pdev->dev, "Failed to add hcd: %d\n", ret); | ||
203 | goto err_disable; | ||
204 | } | ||
205 | device_wakeup_enable(hcd->self.controller); | ||
206 | |||
207 | return 0; | ||
208 | |||
209 | err_disable: | ||
210 | if (jz4740_ohci->vbus) | ||
211 | regulator_disable(jz4740_ohci->vbus); | ||
212 | clk_disable(jz4740_ohci->clk); | ||
213 | |||
214 | err_free: | ||
215 | usb_put_hcd(hcd); | ||
216 | |||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | static int jz4740_ohci_remove(struct platform_device *pdev) | ||
221 | { | ||
222 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
223 | struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd); | ||
224 | |||
225 | usb_remove_hcd(hcd); | ||
226 | |||
227 | if (jz4740_ohci->vbus) | ||
228 | regulator_disable(jz4740_ohci->vbus); | ||
229 | |||
230 | clk_disable(jz4740_ohci->clk); | ||
231 | |||
232 | usb_put_hcd(hcd); | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static struct platform_driver ohci_hcd_jz4740_driver = { | ||
238 | .probe = jz4740_ohci_probe, | ||
239 | .remove = jz4740_ohci_remove, | ||
240 | .driver = { | ||
241 | .name = "jz4740-ohci", | ||
242 | }, | ||
243 | }; | ||
244 | |||
245 | MODULE_ALIAS("platform:jz4740-ohci"); | ||
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index fb947655badd..9c4143112e6c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -1475,6 +1475,32 @@ config MT7621_WDT | |||
1475 | help | 1475 | help |
1476 | Hardware driver for the Mediatek/Ralink MT7621/8 SoC Watchdog Timer. | 1476 | Hardware driver for the Mediatek/Ralink MT7621/8 SoC Watchdog Timer. |
1477 | 1477 | ||
1478 | config PIC32_WDT | ||
1479 | tristate "Microchip PIC32 hardware watchdog" | ||
1480 | select WATCHDOG_CORE | ||
1481 | depends on MACH_PIC32 | ||
1482 | help | ||
1483 | Watchdog driver for the built in watchdog hardware in a PIC32. | ||
1484 | |||
1485 | Configuration bits must be set appropriately for the watchdog to be | ||
1486 | controlled by this driver. | ||
1487 | |||
1488 | To compile this driver as a loadable module, choose M here. | ||
1489 | The module will be called pic32-wdt. | ||
1490 | |||
1491 | config PIC32_DMT | ||
1492 | tristate "Microchip PIC32 Deadman Timer" | ||
1493 | select WATCHDOG_CORE | ||
1494 | depends on MACH_PIC32 | ||
1495 | help | ||
1496 | Watchdog driver for PIC32 instruction fetch counting timer. This specific | ||
1497 | timer is typically be used in misson critical and safety critical | ||
1498 | applications, where any single failure of the software functionality | ||
1499 | and sequencing must be detected. | ||
1500 | |||
1501 | To compile this driver as a loadable module, choose M here. | ||
1502 | The module will be called pic32-dmt. | ||
1503 | |||
1478 | # PARISC Architecture | 1504 | # PARISC Architecture |
1479 | 1505 | ||
1480 | # POWERPC Architecture | 1506 | # POWERPC Architecture |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index feb6270fdbde..9bde095ff691 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -157,6 +157,8 @@ obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o | |||
157 | obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o | 157 | obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o |
158 | obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o | 158 | obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o |
159 | obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o | 159 | obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o |
160 | obj-$(CONFIG_PIC32_WDT) += pic32-wdt.o | ||
161 | obj-$(CONFIG_PIC32_DMT) += pic32-dmt.o | ||
160 | 162 | ||
161 | # PARISC Architecture | 163 | # PARISC Architecture |
162 | 164 | ||
diff --git a/drivers/watchdog/pic32-dmt.c b/drivers/watchdog/pic32-dmt.c new file mode 100644 index 000000000000..962f58c03353 --- /dev/null +++ b/drivers/watchdog/pic32-dmt.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | * PIC32 deadman timer driver | ||
3 | * | ||
4 | * Purna Chandra Mandal <purna.mandal@microchip.com> | ||
5 | * Copyright (c) 2016, Microchip Technology Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | #include <linux/clk.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_device.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/pm.h> | ||
22 | #include <linux/watchdog.h> | ||
23 | |||
24 | #include <asm/mach-pic32/pic32.h> | ||
25 | |||
26 | /* Deadman Timer Regs */ | ||
27 | #define DMTCON_REG 0x00 | ||
28 | #define DMTPRECLR_REG 0x10 | ||
29 | #define DMTCLR_REG 0x20 | ||
30 | #define DMTSTAT_REG 0x30 | ||
31 | #define DMTCNT_REG 0x40 | ||
32 | #define DMTPSCNT_REG 0x60 | ||
33 | #define DMTPSINTV_REG 0x70 | ||
34 | |||
35 | /* Deadman Timer Regs fields */ | ||
36 | #define DMT_ON BIT(15) | ||
37 | #define DMT_STEP1_KEY BIT(6) | ||
38 | #define DMT_STEP2_KEY BIT(3) | ||
39 | #define DMTSTAT_WINOPN BIT(0) | ||
40 | #define DMTSTAT_EVENT BIT(5) | ||
41 | #define DMTSTAT_BAD2 BIT(6) | ||
42 | #define DMTSTAT_BAD1 BIT(7) | ||
43 | |||
44 | /* Reset Control Register fields for watchdog */ | ||
45 | #define RESETCON_DMT_TIMEOUT BIT(5) | ||
46 | |||
47 | struct pic32_dmt { | ||
48 | void __iomem *regs; | ||
49 | struct clk *clk; | ||
50 | }; | ||
51 | |||
52 | static inline void dmt_enable(struct pic32_dmt *dmt) | ||
53 | { | ||
54 | writel(DMT_ON, PIC32_SET(dmt->regs + DMTCON_REG)); | ||
55 | } | ||
56 | |||
57 | static inline void dmt_disable(struct pic32_dmt *dmt) | ||
58 | { | ||
59 | writel(DMT_ON, PIC32_CLR(dmt->regs + DMTCON_REG)); | ||
60 | /* | ||
61 | * Cannot touch registers in the CPU cycle following clearing the | ||
62 | * ON bit. | ||
63 | */ | ||
64 | nop(); | ||
65 | } | ||
66 | |||
67 | static inline int dmt_bad_status(struct pic32_dmt *dmt) | ||
68 | { | ||
69 | u32 val; | ||
70 | |||
71 | val = readl(dmt->regs + DMTSTAT_REG); | ||
72 | val &= (DMTSTAT_BAD1 | DMTSTAT_BAD2 | DMTSTAT_EVENT); | ||
73 | if (val) | ||
74 | return -EAGAIN; | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static inline int dmt_keepalive(struct pic32_dmt *dmt) | ||
80 | { | ||
81 | u32 v; | ||
82 | u32 timeout = 500; | ||
83 | |||
84 | /* set pre-clear key */ | ||
85 | writel(DMT_STEP1_KEY << 8, dmt->regs + DMTPRECLR_REG); | ||
86 | |||
87 | /* wait for DMT window to open */ | ||
88 | while (--timeout) { | ||
89 | v = readl(dmt->regs + DMTSTAT_REG) & DMTSTAT_WINOPN; | ||
90 | if (v == DMTSTAT_WINOPN) | ||
91 | break; | ||
92 | } | ||
93 | |||
94 | /* apply key2 */ | ||
95 | writel(DMT_STEP2_KEY, dmt->regs + DMTCLR_REG); | ||
96 | |||
97 | /* check whether keys are latched correctly */ | ||
98 | return dmt_bad_status(dmt); | ||
99 | } | ||
100 | |||
101 | static inline u32 pic32_dmt_get_timeout_secs(struct pic32_dmt *dmt) | ||
102 | { | ||
103 | unsigned long rate; | ||
104 | |||
105 | rate = clk_get_rate(dmt->clk); | ||
106 | if (rate) | ||
107 | return readl(dmt->regs + DMTPSCNT_REG) / rate; | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static inline u32 pic32_dmt_bootstatus(struct pic32_dmt *dmt) | ||
113 | { | ||
114 | u32 v; | ||
115 | void __iomem *rst_base; | ||
116 | |||
117 | rst_base = ioremap(PIC32_BASE_RESET, 0x10); | ||
118 | if (!rst_base) | ||
119 | return 0; | ||
120 | |||
121 | v = readl(rst_base); | ||
122 | |||
123 | writel(RESETCON_DMT_TIMEOUT, PIC32_CLR(rst_base)); | ||
124 | |||
125 | iounmap(rst_base); | ||
126 | return v & RESETCON_DMT_TIMEOUT; | ||
127 | } | ||
128 | |||
129 | static int pic32_dmt_start(struct watchdog_device *wdd) | ||
130 | { | ||
131 | struct pic32_dmt *dmt = watchdog_get_drvdata(wdd); | ||
132 | |||
133 | dmt_enable(dmt); | ||
134 | return dmt_keepalive(dmt); | ||
135 | } | ||
136 | |||
137 | static int pic32_dmt_stop(struct watchdog_device *wdd) | ||
138 | { | ||
139 | struct pic32_dmt *dmt = watchdog_get_drvdata(wdd); | ||
140 | |||
141 | dmt_disable(dmt); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static int pic32_dmt_ping(struct watchdog_device *wdd) | ||
147 | { | ||
148 | struct pic32_dmt *dmt = watchdog_get_drvdata(wdd); | ||
149 | |||
150 | return dmt_keepalive(dmt); | ||
151 | } | ||
152 | |||
153 | static const struct watchdog_ops pic32_dmt_fops = { | ||
154 | .owner = THIS_MODULE, | ||
155 | .start = pic32_dmt_start, | ||
156 | .stop = pic32_dmt_stop, | ||
157 | .ping = pic32_dmt_ping, | ||
158 | }; | ||
159 | |||
160 | static const struct watchdog_info pic32_dmt_ident = { | ||
161 | .options = WDIOF_KEEPALIVEPING | | ||
162 | WDIOF_MAGICCLOSE, | ||
163 | .identity = "PIC32 Deadman Timer", | ||
164 | }; | ||
165 | |||
166 | static struct watchdog_device pic32_dmt_wdd = { | ||
167 | .info = &pic32_dmt_ident, | ||
168 | .ops = &pic32_dmt_fops, | ||
169 | }; | ||
170 | |||
171 | static int pic32_dmt_probe(struct platform_device *pdev) | ||
172 | { | ||
173 | int ret; | ||
174 | struct pic32_dmt *dmt; | ||
175 | struct resource *mem; | ||
176 | struct watchdog_device *wdd = &pic32_dmt_wdd; | ||
177 | |||
178 | dmt = devm_kzalloc(&pdev->dev, sizeof(*dmt), GFP_KERNEL); | ||
179 | if (IS_ERR(dmt)) | ||
180 | return PTR_ERR(dmt); | ||
181 | |||
182 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
183 | dmt->regs = devm_ioremap_resource(&pdev->dev, mem); | ||
184 | if (IS_ERR(dmt->regs)) | ||
185 | return PTR_ERR(dmt->regs); | ||
186 | |||
187 | dmt->clk = devm_clk_get(&pdev->dev, NULL); | ||
188 | if (IS_ERR(dmt->clk)) { | ||
189 | dev_err(&pdev->dev, "clk not found\n"); | ||
190 | return PTR_ERR(dmt->clk); | ||
191 | } | ||
192 | |||
193 | ret = clk_prepare_enable(dmt->clk); | ||
194 | if (ret) | ||
195 | return ret; | ||
196 | |||
197 | wdd->timeout = pic32_dmt_get_timeout_secs(dmt); | ||
198 | if (!wdd->timeout) { | ||
199 | dev_err(&pdev->dev, | ||
200 | "failed to read watchdog register timeout\n"); | ||
201 | ret = -EINVAL; | ||
202 | goto out_disable_clk; | ||
203 | } | ||
204 | |||
205 | dev_info(&pdev->dev, "timeout %d\n", wdd->timeout); | ||
206 | |||
207 | wdd->bootstatus = pic32_dmt_bootstatus(dmt) ? WDIOF_CARDRESET : 0; | ||
208 | |||
209 | watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); | ||
210 | watchdog_set_drvdata(wdd, dmt); | ||
211 | |||
212 | ret = watchdog_register_device(wdd); | ||
213 | if (ret) { | ||
214 | dev_err(&pdev->dev, "watchdog register failed, err %d\n", ret); | ||
215 | goto out_disable_clk; | ||
216 | } | ||
217 | |||
218 | platform_set_drvdata(pdev, wdd); | ||
219 | return 0; | ||
220 | |||
221 | out_disable_clk: | ||
222 | clk_disable_unprepare(dmt->clk); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | static int pic32_dmt_remove(struct platform_device *pdev) | ||
227 | { | ||
228 | struct watchdog_device *wdd = platform_get_drvdata(pdev); | ||
229 | struct pic32_dmt *dmt = watchdog_get_drvdata(wdd); | ||
230 | |||
231 | watchdog_unregister_device(wdd); | ||
232 | clk_disable_unprepare(dmt->clk); | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static const struct of_device_id pic32_dmt_of_ids[] = { | ||
238 | { .compatible = "microchip,pic32mzda-dmt",}, | ||
239 | { /* sentinel */ } | ||
240 | }; | ||
241 | MODULE_DEVICE_TABLE(of, pic32_dmt_of_ids); | ||
242 | |||
243 | static struct platform_driver pic32_dmt_driver = { | ||
244 | .probe = pic32_dmt_probe, | ||
245 | .remove = pic32_dmt_remove, | ||
246 | .driver = { | ||
247 | .name = "pic32-dmt", | ||
248 | .owner = THIS_MODULE, | ||
249 | .of_match_table = of_match_ptr(pic32_dmt_of_ids), | ||
250 | } | ||
251 | }; | ||
252 | |||
253 | module_platform_driver(pic32_dmt_driver); | ||
254 | |||
255 | MODULE_AUTHOR("Purna Chandra Mandal <purna.mandal@microchip.com>"); | ||
256 | MODULE_DESCRIPTION("Microchip PIC32 DMT Driver"); | ||
257 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/watchdog/pic32-wdt.c b/drivers/watchdog/pic32-wdt.c new file mode 100644 index 000000000000..6047aa89a4d3 --- /dev/null +++ b/drivers/watchdog/pic32-wdt.c | |||
@@ -0,0 +1,263 @@ | |||
1 | /* | ||
2 | * PIC32 watchdog driver | ||
3 | * | ||
4 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
5 | * Copyright (c) 2016, Microchip Technology Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | #include <linux/clk.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_device.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/pm.h> | ||
22 | #include <linux/watchdog.h> | ||
23 | |||
24 | #include <asm/mach-pic32/pic32.h> | ||
25 | |||
26 | /* Watchdog Timer Registers */ | ||
27 | #define WDTCON_REG 0x00 | ||
28 | |||
29 | /* Watchdog Timer Control Register fields */ | ||
30 | #define WDTCON_WIN_EN BIT(0) | ||
31 | #define WDTCON_RMCS_MASK 0x0003 | ||
32 | #define WDTCON_RMCS_SHIFT 0x0006 | ||
33 | #define WDTCON_RMPS_MASK 0x001F | ||
34 | #define WDTCON_RMPS_SHIFT 0x0008 | ||
35 | #define WDTCON_ON BIT(15) | ||
36 | #define WDTCON_CLR_KEY 0x5743 | ||
37 | |||
38 | /* Reset Control Register fields for watchdog */ | ||
39 | #define RESETCON_TIMEOUT_IDLE BIT(2) | ||
40 | #define RESETCON_TIMEOUT_SLEEP BIT(3) | ||
41 | #define RESETCON_WDT_TIMEOUT BIT(4) | ||
42 | |||
43 | struct pic32_wdt { | ||
44 | void __iomem *regs; | ||
45 | void __iomem *rst_base; | ||
46 | struct clk *clk; | ||
47 | }; | ||
48 | |||
49 | static inline bool pic32_wdt_is_win_enabled(struct pic32_wdt *wdt) | ||
50 | { | ||
51 | return !!(readl(wdt->regs + WDTCON_REG) & WDTCON_WIN_EN); | ||
52 | } | ||
53 | |||
54 | static inline u32 pic32_wdt_get_post_scaler(struct pic32_wdt *wdt) | ||
55 | { | ||
56 | u32 v = readl(wdt->regs + WDTCON_REG); | ||
57 | |||
58 | return (v >> WDTCON_RMPS_SHIFT) & WDTCON_RMPS_MASK; | ||
59 | } | ||
60 | |||
61 | static inline u32 pic32_wdt_get_clk_id(struct pic32_wdt *wdt) | ||
62 | { | ||
63 | u32 v = readl(wdt->regs + WDTCON_REG); | ||
64 | |||
65 | return (v >> WDTCON_RMCS_SHIFT) & WDTCON_RMCS_MASK; | ||
66 | } | ||
67 | |||
68 | static int pic32_wdt_bootstatus(struct pic32_wdt *wdt) | ||
69 | { | ||
70 | u32 v = readl(wdt->rst_base); | ||
71 | |||
72 | writel(RESETCON_WDT_TIMEOUT, PIC32_CLR(wdt->rst_base)); | ||
73 | |||
74 | return v & RESETCON_WDT_TIMEOUT; | ||
75 | } | ||
76 | |||
77 | static u32 pic32_wdt_get_timeout_secs(struct pic32_wdt *wdt, struct device *dev) | ||
78 | { | ||
79 | unsigned long rate; | ||
80 | u32 period, ps, terminal; | ||
81 | |||
82 | rate = clk_get_rate(wdt->clk); | ||
83 | |||
84 | dev_dbg(dev, "wdt: clk_id %d, clk_rate %lu (prescale)\n", | ||
85 | pic32_wdt_get_clk_id(wdt), rate); | ||
86 | |||
87 | /* default, prescaler of 32 (i.e. div-by-32) is implicit. */ | ||
88 | rate >>= 5; | ||
89 | if (!rate) | ||
90 | return 0; | ||
91 | |||
92 | /* calculate terminal count from postscaler. */ | ||
93 | ps = pic32_wdt_get_post_scaler(wdt); | ||
94 | terminal = BIT(ps); | ||
95 | |||
96 | /* find time taken (in secs) to reach terminal count */ | ||
97 | period = terminal / rate; | ||
98 | dev_dbg(dev, | ||
99 | "wdt: clk_rate %lu (postscale) / terminal %d, timeout %dsec\n", | ||
100 | rate, terminal, period); | ||
101 | |||
102 | return period; | ||
103 | } | ||
104 | |||
105 | static void pic32_wdt_keepalive(struct pic32_wdt *wdt) | ||
106 | { | ||
107 | /* write key through single half-word */ | ||
108 | writew(WDTCON_CLR_KEY, wdt->regs + WDTCON_REG + 2); | ||
109 | } | ||
110 | |||
111 | static int pic32_wdt_start(struct watchdog_device *wdd) | ||
112 | { | ||
113 | struct pic32_wdt *wdt = watchdog_get_drvdata(wdd); | ||
114 | |||
115 | writel(WDTCON_ON, PIC32_SET(wdt->regs + WDTCON_REG)); | ||
116 | pic32_wdt_keepalive(wdt); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static int pic32_wdt_stop(struct watchdog_device *wdd) | ||
122 | { | ||
123 | struct pic32_wdt *wdt = watchdog_get_drvdata(wdd); | ||
124 | |||
125 | writel(WDTCON_ON, PIC32_CLR(wdt->regs + WDTCON_REG)); | ||
126 | |||
127 | /* | ||
128 | * Cannot touch registers in the CPU cycle following clearing the | ||
129 | * ON bit. | ||
130 | */ | ||
131 | nop(); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int pic32_wdt_ping(struct watchdog_device *wdd) | ||
137 | { | ||
138 | struct pic32_wdt *wdt = watchdog_get_drvdata(wdd); | ||
139 | |||
140 | pic32_wdt_keepalive(wdt); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static const struct watchdog_ops pic32_wdt_fops = { | ||
146 | .owner = THIS_MODULE, | ||
147 | .start = pic32_wdt_start, | ||
148 | .stop = pic32_wdt_stop, | ||
149 | .ping = pic32_wdt_ping, | ||
150 | }; | ||
151 | |||
152 | static const struct watchdog_info pic32_wdt_ident = { | ||
153 | .options = WDIOF_KEEPALIVEPING | | ||
154 | WDIOF_MAGICCLOSE | WDIOF_CARDRESET, | ||
155 | .identity = "PIC32 Watchdog", | ||
156 | }; | ||
157 | |||
158 | static struct watchdog_device pic32_wdd = { | ||
159 | .info = &pic32_wdt_ident, | ||
160 | .ops = &pic32_wdt_fops, | ||
161 | }; | ||
162 | |||
163 | static const struct of_device_id pic32_wdt_dt_ids[] = { | ||
164 | { .compatible = "microchip,pic32mzda-wdt", }, | ||
165 | { /* sentinel */ } | ||
166 | }; | ||
167 | MODULE_DEVICE_TABLE(of, pic32_wdt_dt_ids); | ||
168 | |||
169 | static int pic32_wdt_drv_probe(struct platform_device *pdev) | ||
170 | { | ||
171 | int ret; | ||
172 | struct watchdog_device *wdd = &pic32_wdd; | ||
173 | struct pic32_wdt *wdt; | ||
174 | struct resource *mem; | ||
175 | |||
176 | wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); | ||
177 | if (IS_ERR(wdt)) | ||
178 | return PTR_ERR(wdt); | ||
179 | |||
180 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
181 | wdt->regs = devm_ioremap_resource(&pdev->dev, mem); | ||
182 | if (IS_ERR(wdt->regs)) | ||
183 | return PTR_ERR(wdt->regs); | ||
184 | |||
185 | wdt->rst_base = devm_ioremap(&pdev->dev, PIC32_BASE_RESET, 0x10); | ||
186 | if (IS_ERR(wdt->rst_base)) | ||
187 | return PTR_ERR(wdt->rst_base); | ||
188 | |||
189 | wdt->clk = devm_clk_get(&pdev->dev, NULL); | ||
190 | if (IS_ERR(wdt->clk)) { | ||
191 | dev_err(&pdev->dev, "clk not found\n"); | ||
192 | return PTR_ERR(wdt->clk); | ||
193 | } | ||
194 | |||
195 | ret = clk_prepare_enable(wdt->clk); | ||
196 | if (ret) { | ||
197 | dev_err(&pdev->dev, "clk enable failed\n"); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | if (pic32_wdt_is_win_enabled(wdt)) { | ||
202 | dev_err(&pdev->dev, "windowed-clear mode is not supported.\n"); | ||
203 | ret = -ENODEV; | ||
204 | goto out_disable_clk; | ||
205 | } | ||
206 | |||
207 | wdd->timeout = pic32_wdt_get_timeout_secs(wdt, &pdev->dev); | ||
208 | if (!wdd->timeout) { | ||
209 | dev_err(&pdev->dev, | ||
210 | "failed to read watchdog register timeout\n"); | ||
211 | ret = -EINVAL; | ||
212 | goto out_disable_clk; | ||
213 | } | ||
214 | |||
215 | dev_info(&pdev->dev, "timeout %d\n", wdd->timeout); | ||
216 | |||
217 | wdd->bootstatus = pic32_wdt_bootstatus(wdt) ? WDIOF_CARDRESET : 0; | ||
218 | |||
219 | watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); | ||
220 | watchdog_set_drvdata(wdd, wdt); | ||
221 | |||
222 | ret = watchdog_register_device(wdd); | ||
223 | if (ret) { | ||
224 | dev_err(&pdev->dev, "watchdog register failed, err %d\n", ret); | ||
225 | goto out_disable_clk; | ||
226 | } | ||
227 | |||
228 | platform_set_drvdata(pdev, wdd); | ||
229 | |||
230 | return 0; | ||
231 | |||
232 | out_disable_clk: | ||
233 | clk_disable_unprepare(wdt->clk); | ||
234 | |||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | static int pic32_wdt_drv_remove(struct platform_device *pdev) | ||
239 | { | ||
240 | struct watchdog_device *wdd = platform_get_drvdata(pdev); | ||
241 | struct pic32_wdt *wdt = watchdog_get_drvdata(wdd); | ||
242 | |||
243 | watchdog_unregister_device(wdd); | ||
244 | clk_disable_unprepare(wdt->clk); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static struct platform_driver pic32_wdt_driver = { | ||
250 | .probe = pic32_wdt_drv_probe, | ||
251 | .remove = pic32_wdt_drv_remove, | ||
252 | .driver = { | ||
253 | .name = "pic32-wdt", | ||
254 | .owner = THIS_MODULE, | ||
255 | .of_match_table = of_match_ptr(pic32_wdt_dt_ids), | ||
256 | } | ||
257 | }; | ||
258 | |||
259 | module_platform_driver(pic32_wdt_driver); | ||
260 | |||
261 | MODULE_AUTHOR("Joshua Henderson <joshua.henderson@microchip.com>"); | ||
262 | MODULE_DESCRIPTION("Microchip PIC32 Watchdog Timer"); | ||
263 | MODULE_LICENSE("GPL"); | ||
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 8afe10cf7df8..8ab782d8b33d 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -1071,7 +1071,7 @@ static int __init parse_crash_elf32_headers(void) | |||
1071 | /* Do some basic Verification. */ | 1071 | /* Do some basic Verification. */ |
1072 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || | 1072 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || |
1073 | (ehdr.e_type != ET_CORE) || | 1073 | (ehdr.e_type != ET_CORE) || |
1074 | !elf_check_arch(&ehdr) || | 1074 | !vmcore_elf32_check_arch(&ehdr) || |
1075 | ehdr.e_ident[EI_CLASS] != ELFCLASS32|| | 1075 | ehdr.e_ident[EI_CLASS] != ELFCLASS32|| |
1076 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || | 1076 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || |
1077 | ehdr.e_version != EV_CURRENT || | 1077 | ehdr.e_version != EV_CURRENT || |
diff --git a/include/asm-generic/seccomp.h b/include/asm-generic/seccomp.h index c9ccafa0d99a..e74072d23e69 100644 --- a/include/asm-generic/seccomp.h +++ b/include/asm-generic/seccomp.h | |||
@@ -29,4 +29,18 @@ | |||
29 | #define __NR_seccomp_sigreturn __NR_rt_sigreturn | 29 | #define __NR_seccomp_sigreturn __NR_rt_sigreturn |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #ifdef CONFIG_COMPAT | ||
33 | #ifndef get_compat_mode1_syscalls | ||
34 | static inline const int *get_compat_mode1_syscalls(void) | ||
35 | { | ||
36 | static const int mode1_syscalls_32[] = { | ||
37 | __NR_seccomp_read_32, __NR_seccomp_write_32, | ||
38 | __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, | ||
39 | 0, /* null terminated */ | ||
40 | }; | ||
41 | return mode1_syscalls_32; | ||
42 | } | ||
43 | #endif | ||
44 | #endif /* CONFIG_COMPAT */ | ||
45 | |||
32 | #endif /* _ASM_GENERIC_SECCOMP_H */ | 46 | #endif /* _ASM_GENERIC_SECCOMP_H */ |
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h index 3d1a3af5cf59..a2508a8f9a9c 100644 --- a/include/asm-generic/siginfo.h +++ b/include/asm-generic/siginfo.h | |||
@@ -17,21 +17,6 @@ | |||
17 | struct siginfo; | 17 | struct siginfo; |
18 | void do_schedule_next_timer(struct siginfo *info); | 18 | void do_schedule_next_timer(struct siginfo *info); |
19 | 19 | ||
20 | #ifndef HAVE_ARCH_COPY_SIGINFO | ||
21 | |||
22 | #include <linux/string.h> | ||
23 | |||
24 | static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) | ||
25 | { | ||
26 | if (from->si_code < 0) | ||
27 | memcpy(to, from, sizeof(*to)); | ||
28 | else | ||
29 | /* _sigchld is currently the largest know union member */ | ||
30 | memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld)); | ||
31 | } | ||
32 | |||
33 | #endif | ||
34 | |||
35 | extern int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); | 20 | extern int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); |
36 | 21 | ||
37 | #endif | 22 | #endif |
diff --git a/include/dt-bindings/clock/ath79-clk.h b/include/dt-bindings/clock/ath79-clk.h new file mode 100644 index 000000000000..27359ad83904 --- /dev/null +++ b/include/dt-bindings/clock/ath79-clk.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2016 Antony Pavlov <antonynpavlov@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef __DT_BINDINGS_ATH79_CLK_H | ||
11 | #define __DT_BINDINGS_ATH79_CLK_H | ||
12 | |||
13 | #define ATH79_CLK_CPU 0 | ||
14 | #define ATH79_CLK_DDR 1 | ||
15 | #define ATH79_CLK_AHB 2 | ||
16 | |||
17 | #define ATH79_CLK_END 3 | ||
18 | |||
19 | #endif /* __DT_BINDINGS_ATH79_CLK_H */ | ||
diff --git a/include/dt-bindings/clock/microchip,pic32-clock.h b/include/dt-bindings/clock/microchip,pic32-clock.h new file mode 100644 index 000000000000..184647a6a8de --- /dev/null +++ b/include/dt-bindings/clock/microchip,pic32-clock.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Purna Chandra Mandal,<purna.mandal@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _DT_BINDINGS_CLK_MICROCHIP_PIC32_H_ | ||
16 | #define _DT_BINDINGS_CLK_MICROCHIP_PIC32_H_ | ||
17 | |||
18 | /* clock output indices */ | ||
19 | #define POSCCLK 0 | ||
20 | #define FRCCLK 1 | ||
21 | #define BFRCCLK 2 | ||
22 | #define LPRCCLK 3 | ||
23 | #define SOSCCLK 4 | ||
24 | #define FRCDIVCLK 5 | ||
25 | #define PLLCLK 6 | ||
26 | #define SCLK 7 | ||
27 | #define PB1CLK 8 | ||
28 | #define PB2CLK 9 | ||
29 | #define PB3CLK 10 | ||
30 | #define PB4CLK 11 | ||
31 | #define PB5CLK 12 | ||
32 | #define PB6CLK 13 | ||
33 | #define PB7CLK 14 | ||
34 | #define REF1CLK 15 | ||
35 | #define REF2CLK 16 | ||
36 | #define REF3CLK 17 | ||
37 | #define REF4CLK 18 | ||
38 | #define REF5CLK 19 | ||
39 | #define UPLLCLK 20 | ||
40 | #define MAXCLKS 21 | ||
41 | |||
42 | #endif /* _DT_BINDINGS_CLK_MICROCHIP_PIC32_H_ */ | ||
diff --git a/include/linux/bcm47xx_sprom.h b/include/linux/bcm47xx_sprom.h new file mode 100644 index 000000000000..c06b47c84e1a --- /dev/null +++ b/include/linux/bcm47xx_sprom.h | |||
@@ -0,0 +1,24 @@ | |||
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 as published by the | ||
4 | * Free Software Foundation; either version 2 of the License, or (at your | ||
5 | * option) any later version. | ||
6 | */ | ||
7 | |||
8 | #ifndef __BCM47XX_SPROM_H | ||
9 | #define __BCM47XX_SPROM_H | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/vmalloc.h> | ||
14 | |||
15 | #ifdef CONFIG_BCM47XX_SPROM | ||
16 | int bcm47xx_sprom_register_fallbacks(void); | ||
17 | #else | ||
18 | static inline int bcm47xx_sprom_register_fallbacks(void) | ||
19 | { | ||
20 | return -ENOTSUPP; | ||
21 | }; | ||
22 | #endif | ||
23 | |||
24 | #endif /* __BCM47XX_SPROM_H */ | ||
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 3849fce7ecfe..3873697ba21c 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h | |||
@@ -34,9 +34,13 @@ void vmcore_cleanup(void); | |||
34 | 34 | ||
35 | /* | 35 | /* |
36 | * Architecture code can redefine this if there are any special checks | 36 | * Architecture code can redefine this if there are any special checks |
37 | * needed for 64-bit ELF vmcores. In case of 32-bit only architecture, | 37 | * needed for 32-bit ELF or 64-bit ELF vmcores. In case of 32-bit |
38 | * this can be set to zero. | 38 | * only architecture, vmcore_elf64_check_arch can be set to zero. |
39 | */ | 39 | */ |
40 | #ifndef vmcore_elf32_check_arch | ||
41 | #define vmcore_elf32_check_arch(x) elf_check_arch(x) | ||
42 | #endif | ||
43 | |||
40 | #ifndef vmcore_elf64_check_arch | 44 | #ifndef vmcore_elf64_check_arch |
41 | #define vmcore_elf64_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x)) | 45 | #define vmcore_elf64_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x)) |
42 | #endif | 46 | #endif |
diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h index 80f89e4a29ac..81f930b0bca9 100644 --- a/include/linux/irqchip/mips-gic.h +++ b/include/linux/irqchip/mips-gic.h | |||
@@ -103,6 +103,7 @@ | |||
103 | #define GIC_VPE_SWINT0_MAP_OFS 0x0054 | 103 | #define GIC_VPE_SWINT0_MAP_OFS 0x0054 |
104 | #define GIC_VPE_SWINT1_MAP_OFS 0x0058 | 104 | #define GIC_VPE_SWINT1_MAP_OFS 0x0058 |
105 | #define GIC_VPE_OTHER_ADDR_OFS 0x0080 | 105 | #define GIC_VPE_OTHER_ADDR_OFS 0x0080 |
106 | #define GIC_VP_IDENT_OFS 0x0088 | ||
106 | #define GIC_VPE_WD_CONFIG0_OFS 0x0090 | 107 | #define GIC_VPE_WD_CONFIG0_OFS 0x0090 |
107 | #define GIC_VPE_WD_COUNT0_OFS 0x0094 | 108 | #define GIC_VPE_WD_COUNT0_OFS 0x0094 |
108 | #define GIC_VPE_WD_INITIAL0_OFS 0x0098 | 109 | #define GIC_VPE_WD_INITIAL0_OFS 0x0098 |
@@ -211,6 +212,10 @@ | |||
211 | #define GIC_VPE_SMASK_FDC_SHF 6 | 212 | #define GIC_VPE_SMASK_FDC_SHF 6 |
212 | #define GIC_VPE_SMASK_FDC_MSK (MSK(1) << GIC_VPE_SMASK_FDC_SHF) | 213 | #define GIC_VPE_SMASK_FDC_MSK (MSK(1) << GIC_VPE_SMASK_FDC_SHF) |
213 | 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 | |||
214 | /* GIC nomenclature for Core Interrupt Pins. */ | 219 | /* GIC nomenclature for Core Interrupt Pins. */ |
215 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ | 220 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ |
216 | #define GIC_CPU_INT1 1 /* . */ | 221 | #define GIC_CPU_INT1 1 /* . */ |
@@ -278,4 +283,16 @@ static inline int gic_get_usm_range(struct resource *gic_usm_res) | |||
278 | 283 | ||
279 | #endif /* CONFIG_MIPS_GIC */ | 284 | #endif /* CONFIG_MIPS_GIC */ |
280 | 285 | ||
286 | /** | ||
287 | * gic_read_local_vp_id() - read the local VPs VCNUM | ||
288 | * | ||
289 | * Read the VCNUM of the local VP from the GIC_VP_IDENT register and | ||
290 | * return it to the caller. This ID should be used to refer to the VP | ||
291 | * via the GICs VP-other region, or when calculating an offset to a | ||
292 | * bit representing the VP in interrupt masks. | ||
293 | * | ||
294 | * Return: The VCNUM value for the local VP. | ||
295 | */ | ||
296 | extern unsigned gic_read_local_vp_id(void); | ||
297 | |||
281 | #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */ | 298 | #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */ |
diff --git a/include/linux/signal.h b/include/linux/signal.h index 3fbe81444d31..639be264f5f9 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -28,6 +28,21 @@ struct sigpending { | |||
28 | sigset_t signal; | 28 | sigset_t signal; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | #ifndef HAVE_ARCH_COPY_SIGINFO | ||
32 | |||
33 | #include <linux/string.h> | ||
34 | |||
35 | static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) | ||
36 | { | ||
37 | if (from->si_code < 0) | ||
38 | memcpy(to, from, sizeof(*to)); | ||
39 | else | ||
40 | /* _sigchld is currently the largest know union member */ | ||
41 | memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld)); | ||
42 | } | ||
43 | |||
44 | #endif | ||
45 | |||
31 | /* | 46 | /* |
32 | * Define some primitives to manipulate sigset_t. | 47 | * Define some primitives to manipulate sigset_t. |
33 | */ | 48 | */ |
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index e513a4ee369b..24da334af7f1 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h | |||
@@ -264,4 +264,7 @@ | |||
264 | /* MVEBU UART */ | 264 | /* MVEBU UART */ |
265 | #define PORT_MVEBU 114 | 265 | #define PORT_MVEBU 114 |
266 | 266 | ||
267 | /* Microchip PIC32 UART */ | ||
268 | #define PORT_PIC32 115 | ||
269 | |||
267 | #endif /* _UAPILINUX_SERIAL_CORE_H */ | 270 | #endif /* _UAPILINUX_SERIAL_CORE_H */ |
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 6c9bb62ed046..7002796f14a4 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
@@ -513,24 +513,17 @@ static void seccomp_send_sigsys(int syscall, int reason) | |||
513 | * To be fully secure this must be combined with rlimit | 513 | * To be fully secure this must be combined with rlimit |
514 | * to limit the stack allocations too. | 514 | * to limit the stack allocations too. |
515 | */ | 515 | */ |
516 | static int mode1_syscalls[] = { | 516 | static const int mode1_syscalls[] = { |
517 | __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn, | 517 | __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn, |
518 | 0, /* null terminated */ | 518 | 0, /* null terminated */ |
519 | }; | 519 | }; |
520 | 520 | ||
521 | #ifdef CONFIG_COMPAT | ||
522 | static int mode1_syscalls_32[] = { | ||
523 | __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, | ||
524 | 0, /* null terminated */ | ||
525 | }; | ||
526 | #endif | ||
527 | |||
528 | static void __secure_computing_strict(int this_syscall) | 521 | static void __secure_computing_strict(int this_syscall) |
529 | { | 522 | { |
530 | int *syscall_whitelist = mode1_syscalls; | 523 | const int *syscall_whitelist = mode1_syscalls; |
531 | #ifdef CONFIG_COMPAT | 524 | #ifdef CONFIG_COMPAT |
532 | if (in_compat_syscall()) | 525 | if (in_compat_syscall()) |
533 | syscall_whitelist = mode1_syscalls_32; | 526 | syscall_whitelist = get_compat_mode1_syscalls(); |
534 | #endif | 527 | #endif |
535 | do { | 528 | do { |
536 | if (*syscall_whitelist == this_syscall) | 529 | if (*syscall_whitelist == this_syscall) |
diff --git a/scripts/ld-version.sh b/scripts/ld-version.sh index 7bfe9fa1c8dc..d135882e2c40 100755 --- a/scripts/ld-version.sh +++ b/scripts/ld-version.sh | |||
@@ -5,6 +5,6 @@ | |||
5 | gsub(".*version ", ""); | 5 | gsub(".*version ", ""); |
6 | gsub("-.*", ""); | 6 | gsub("-.*", ""); |
7 | split($1,a, "."); | 7 | split($1,a, "."); |
8 | print a[1]*100000000 + a[2]*1000000 + a[3]*10000 + a[4]*100 + a[5]; | 8 | print a[1]*100000000 + a[2]*1000000 + a[3]*10000; |
9 | exit | 9 | exit |
10 | } | 10 | } |
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 150829dd7998..7947e568e057 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Test code for seccomp bpf. | 5 | * Test code for seccomp bpf. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <sys/types.h> | ||
8 | #include <asm/siginfo.h> | 9 | #include <asm/siginfo.h> |
9 | #define __have_siginfo_t 1 | 10 | #define __have_siginfo_t 1 |
10 | #define __have_sigval_t 1 | 11 | #define __have_sigval_t 1 |
@@ -14,7 +15,6 @@ | |||
14 | #include <linux/filter.h> | 15 | #include <linux/filter.h> |
15 | #include <sys/prctl.h> | 16 | #include <sys/prctl.h> |
16 | #include <sys/ptrace.h> | 17 | #include <sys/ptrace.h> |
17 | #include <sys/types.h> | ||
18 | #include <sys/user.h> | 18 | #include <sys/user.h> |
19 | #include <linux/prctl.h> | 19 | #include <linux/prctl.h> |
20 | #include <linux/ptrace.h> | 20 | #include <linux/ptrace.h> |
@@ -1242,6 +1242,12 @@ TEST_F(TRACE_poke, getpid_runs_normally) | |||
1242 | # define ARCH_REGS s390_regs | 1242 | # define ARCH_REGS s390_regs |
1243 | # define SYSCALL_NUM gprs[2] | 1243 | # define SYSCALL_NUM gprs[2] |
1244 | # define SYSCALL_RET gprs[2] | 1244 | # define SYSCALL_RET gprs[2] |
1245 | #elif defined(__mips__) | ||
1246 | # define ARCH_REGS struct pt_regs | ||
1247 | # define SYSCALL_NUM regs[2] | ||
1248 | # define SYSCALL_SYSCALL_NUM regs[4] | ||
1249 | # define SYSCALL_RET regs[2] | ||
1250 | # define SYSCALL_NUM_RET_SHARE_REG | ||
1245 | #else | 1251 | #else |
1246 | # error "Do not know how to find your architecture's registers and syscalls" | 1252 | # error "Do not know how to find your architecture's registers and syscalls" |
1247 | #endif | 1253 | #endif |
@@ -1249,7 +1255,7 @@ TEST_F(TRACE_poke, getpid_runs_normally) | |||
1249 | /* Use PTRACE_GETREGS and PTRACE_SETREGS when available. This is useful for | 1255 | /* Use PTRACE_GETREGS and PTRACE_SETREGS when available. This is useful for |
1250 | * architectures without HAVE_ARCH_TRACEHOOK (e.g. User-mode Linux). | 1256 | * architectures without HAVE_ARCH_TRACEHOOK (e.g. User-mode Linux). |
1251 | */ | 1257 | */ |
1252 | #if defined(__x86_64__) || defined(__i386__) | 1258 | #if defined(__x86_64__) || defined(__i386__) || defined(__mips__) |
1253 | #define HAVE_GETREGS | 1259 | #define HAVE_GETREGS |
1254 | #endif | 1260 | #endif |
1255 | 1261 | ||
@@ -1273,6 +1279,10 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee) | |||
1273 | } | 1279 | } |
1274 | #endif | 1280 | #endif |
1275 | 1281 | ||
1282 | #if defined(__mips__) | ||
1283 | if (regs.SYSCALL_NUM == __NR_O32_Linux) | ||
1284 | return regs.SYSCALL_SYSCALL_NUM; | ||
1285 | #endif | ||
1276 | return regs.SYSCALL_NUM; | 1286 | return regs.SYSCALL_NUM; |
1277 | } | 1287 | } |
1278 | 1288 | ||
@@ -1297,6 +1307,13 @@ void change_syscall(struct __test_metadata *_metadata, | |||
1297 | { | 1307 | { |
1298 | regs.SYSCALL_NUM = syscall; | 1308 | regs.SYSCALL_NUM = syscall; |
1299 | } | 1309 | } |
1310 | #elif defined(__mips__) | ||
1311 | { | ||
1312 | if (regs.SYSCALL_NUM == __NR_O32_Linux) | ||
1313 | regs.SYSCALL_SYSCALL_NUM = syscall; | ||
1314 | else | ||
1315 | regs.SYSCALL_NUM = syscall; | ||
1316 | } | ||
1300 | 1317 | ||
1301 | #elif defined(__arm__) | 1318 | #elif defined(__arm__) |
1302 | # ifndef PTRACE_SET_SYSCALL | 1319 | # ifndef PTRACE_SET_SYSCALL |
@@ -1327,7 +1344,11 @@ void change_syscall(struct __test_metadata *_metadata, | |||
1327 | 1344 | ||
1328 | /* If syscall is skipped, change return value. */ | 1345 | /* If syscall is skipped, change return value. */ |
1329 | if (syscall == -1) | 1346 | if (syscall == -1) |
1347 | #ifdef SYSCALL_NUM_RET_SHARE_REG | ||
1348 | TH_LOG("Can't modify syscall return on this architecture"); | ||
1349 | #else | ||
1330 | regs.SYSCALL_RET = 1; | 1350 | regs.SYSCALL_RET = 1; |
1351 | #endif | ||
1331 | 1352 | ||
1332 | #ifdef HAVE_GETREGS | 1353 | #ifdef HAVE_GETREGS |
1333 | ret = ptrace(PTRACE_SETREGS, tracee, 0, ®s); | 1354 | ret = ptrace(PTRACE_SETREGS, tracee, 0, ®s); |
@@ -1465,8 +1486,13 @@ TEST_F(TRACE_syscall, syscall_dropped) | |||
1465 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0); | 1486 | ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0); |
1466 | ASSERT_EQ(0, ret); | 1487 | ASSERT_EQ(0, ret); |
1467 | 1488 | ||
1489 | #ifdef SYSCALL_NUM_RET_SHARE_REG | ||
1490 | /* gettid has been skipped */ | ||
1491 | EXPECT_EQ(-1, syscall(__NR_gettid)); | ||
1492 | #else | ||
1468 | /* gettid has been skipped and an altered return value stored. */ | 1493 | /* gettid has been skipped and an altered return value stored. */ |
1469 | EXPECT_EQ(1, syscall(__NR_gettid)); | 1494 | EXPECT_EQ(1, syscall(__NR_gettid)); |
1495 | #endif | ||
1470 | EXPECT_NE(self->mytid, syscall(__NR_gettid)); | 1496 | EXPECT_NE(self->mytid, syscall(__NR_gettid)); |
1471 | } | 1497 | } |
1472 | 1498 | ||