aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-05 14:28:25 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-05 14:28:25 -0500
commitd9862cfbe2099deb83f0e9c1932c91f2d9c50464 (patch)
tree7092ef41113269f30b5429868a9d161e171c746d
parent8feed3efa8022107bcb3432ac3ec9917e078ae70 (diff)
parentaeb669d41ffabb91b1542f1f802cb12a989fced0 (diff)
Merge tag 'mips_5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS updates from Paul Burton: - Support for the MIPSr6 MemoryMapID register & Global INValidate TLB (GINVT) instructions, allowing for more efficient TLB maintenance when running on a CPU such as the I6500 that supports these. - Enable huge page support for MIPS64r6. - Optimize post-DMA cache sync by removing that code entirely for kernel configurations in which we know it won't be needed. - The number of pages allocated for interrupt stacks is now calculated correctly, where before we would wastefully allocate too much memory in some configurations. - The ath79 platform migrates to devicetree. - The bcm47xx platform sees fixes for the Buffalo WHR-G54S board. - The ingenic/jz4740 platform gains support for appended devicetrees. - The cavium_octeon, lantiq, loongson32 & sgi-ip27 platforms all see cleanups as do various pieces of core architecture code. * tag 'mips_5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (66 commits) MIPS: lantiq: Remove separate GPHY Firmware loader MIPS: ingenic: Add support for appended devicetree MIPS: SGI-IP27: rework HUB interrupts MIPS: SGI-IP27: do boot CPU init later MIPS: SGI-IP27: do xtalk scanning later MIPS: SGI-IP27: use pr_info/pr_emerg and pr_cont to fix output MIPS: SGI-IP27: clean up bridge access and header files MIPS: SGI-IP27: get rid of volatile and hubreg_t MIPS: irq: Allocate accurate order pages for irq stack MIPS: dma-noncoherent: Remove bogus condition in dma_sync_phys() MIPS: eBPF: Remove REG_32BIT_ZERO_EX MIPS: eBPF: Always return sign extended 32b values MIPS: CM: Fix indentation MIPS: BCM47XX: Fix/improve Buffalo WHR-G54S support MIPS: OCTEON: program rx/tx-delay always from DT MIPS: OCTEON: delete board-specific link status MIPS: OCTEON: don't lie about interface type of CN3005 board MIPS: OCTEON: warn if deprecated link status is being used MIPS: OCTEON: add fixed-link nodes to in-kernel device tree MIPS: Delete unused flush_cache_sigtramp() ...
-rw-r--r--Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt36
-rw-r--r--Documentation/devicetree/bindings/mips/lantiq/rcu.txt18
-rw-r--r--arch/mips/Kconfig13
-rw-r--r--arch/mips/Makefile2
-rw-r--r--arch/mips/ath79/Kconfig73
-rw-r--r--arch/mips/ath79/Makefile23
-rw-r--r--arch/mips/ath79/clock.c342
-rw-r--r--arch/mips/ath79/common.h5
-rw-r--r--arch/mips/ath79/dev-common.c159
-rw-r--r--arch/mips/ath79/dev-common.h18
-rw-r--r--arch/mips/ath79/dev-gpio-buttons.c56
-rw-r--r--arch/mips/ath79/dev-gpio-buttons.h23
-rw-r--r--arch/mips/ath79/dev-leds-gpio.c54
-rw-r--r--arch/mips/ath79/dev-leds-gpio.h21
-rw-r--r--arch/mips/ath79/dev-spi.c38
-rw-r--r--arch/mips/ath79/dev-spi.h22
-rw-r--r--arch/mips/ath79/dev-usb.c242
-rw-r--r--arch/mips/ath79/dev-usb.h17
-rw-r--r--arch/mips/ath79/dev-wmac.c155
-rw-r--r--arch/mips/ath79/dev-wmac.h17
-rw-r--r--arch/mips/ath79/irq.c169
-rw-r--r--arch/mips/ath79/mach-ap121.c92
-rw-r--r--arch/mips/ath79/mach-ap136.c156
-rw-r--r--arch/mips/ath79/mach-ap81.c100
-rw-r--r--arch/mips/ath79/mach-db120.c136
-rw-r--r--arch/mips/ath79/mach-pb44.c128
-rw-r--r--arch/mips/ath79/mach-ubnt-xm.c126
-rw-r--r--arch/mips/ath79/machtypes.h28
-rw-r--r--arch/mips/ath79/pci.c273
-rw-r--r--arch/mips/ath79/pci.h35
-rw-r--r--arch/mips/ath79/setup.c78
-rw-r--r--arch/mips/bcm47xx/buttons.c2
-rw-r--r--arch/mips/bcm47xx/leds.c10
-rw-r--r--arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts14
-rw-r--r--arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts6
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-board.c86
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper.c39
-rw-r--r--arch/mips/cavium-octeon/oct_ilm.c32
-rw-r--r--arch/mips/cavium-octeon/octeon-platform.c64
-rw-r--r--arch/mips/configs/xway_defconfig1
-rw-r--r--arch/mips/include/asm/Kbuild1
-rw-r--r--arch/mips/include/asm/barrier.h19
-rw-r--r--arch/mips/include/asm/cacheflush.h2
-rw-r--r--arch/mips/include/asm/cmpxchg.h104
-rw-r--r--arch/mips/include/asm/cpu-features.h13
-rw-r--r--arch/mips/include/asm/cpu.h1
-rw-r--r--arch/mips/include/asm/ginvt.h56
-rw-r--r--arch/mips/include/asm/irqflags.h2
-rw-r--r--arch/mips/include/asm/mach-ath79/ath79.h4
-rw-r--r--arch/mips/include/asm/mach-ip27/irq.h12
-rw-r--r--arch/mips/include/asm/mach-ip27/mmzone.h9
-rw-r--r--arch/mips/include/asm/mach-loongson32/platform.h4
-rw-r--r--arch/mips/include/asm/mipsregs.h11
-rw-r--r--arch/mips/include/asm/mmu.h6
-rw-r--r--arch/mips/include/asm/mmu_context.h139
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-board.h12
-rw-r--r--arch/mips/include/asm/octeon/cvmx-smix-defs.h276
-rw-r--r--arch/mips/include/asm/pci/bridge.h206
-rw-r--r--arch/mips/include/asm/pgtable.h51
-rw-r--r--arch/mips/include/asm/smp-ops.h1
-rw-r--r--arch/mips/include/asm/sn/addrs.h72
-rw-r--r--arch/mips/include/asm/sn/arch.h2
-rw-r--r--arch/mips/include/asm/sn/io.h2
-rw-r--r--arch/mips/include/asm/sn/sn0/addrs.h5
-rw-r--r--arch/mips/include/asm/tlbflush.h5
-rw-r--r--arch/mips/jz4740/setup.c14
-rw-r--r--arch/mips/kernel/cpu-probe.c55
-rw-r--r--arch/mips/kernel/irq.c4
-rw-r--r--arch/mips/kernel/mips-cm.c4
-rw-r--r--arch/mips/kernel/mips-r2-to-r6-emul.c21
-rw-r--r--arch/mips/kernel/segment.c15
-rw-r--r--arch/mips/kernel/setup.c7
-rw-r--r--arch/mips/kernel/smp.c69
-rw-r--r--arch/mips/kernel/spinlock_test.c21
-rw-r--r--arch/mips/kernel/traps.c4
-rw-r--r--arch/mips/kernel/unaligned.c17
-rw-r--r--arch/mips/kvm/emulate.c8
-rw-r--r--arch/mips/kvm/mips.c5
-rw-r--r--arch/mips/kvm/trap_emul.c30
-rw-r--r--arch/mips/kvm/vz.c8
-rw-r--r--arch/mips/lantiq/Kconfig4
-rw-r--r--arch/mips/lib/dump_tlb.c22
-rw-r--r--arch/mips/loongson32/Kconfig2
-rw-r--r--arch/mips/loongson32/Platform4
-rw-r--r--arch/mips/loongson32/common/platform.c63
-rw-r--r--arch/mips/loongson32/ls1b/board.c28
-rw-r--r--arch/mips/math-emu/me-debugfs.c23
-rw-r--r--arch/mips/mm/Makefile16
-rw-r--r--arch/mips/mm/c-octeon.c18
-rw-r--r--arch/mips/mm/c-r3k.c25
-rw-r--r--arch/mips/mm/c-r4k.c124
-rw-r--r--arch/mips/mm/c-tx39.c21
-rw-r--r--arch/mips/mm/cache.c1
-rw-r--r--arch/mips/mm/context.c291
-rw-r--r--arch/mips/mm/dma-noncoherent.c9
-rw-r--r--arch/mips/mm/init.c7
-rw-r--r--arch/mips/mm/sc-debugfs.c15
-rw-r--r--arch/mips/mm/tlb-r3k.c14
-rw-r--r--arch/mips/mm/tlb-r4k.c71
-rw-r--r--arch/mips/mm/tlb-r8k.c10
-rw-r--r--arch/mips/pci/Makefile1
-rw-r--r--arch/mips/pci/fixup-ath79.c21
-rw-r--r--arch/mips/pci/ops-bridge.c68
-rw-r--r--arch/mips/pci/pci-ip27.c49
-rw-r--r--arch/mips/ralink/bootrom.c8
-rw-r--r--arch/mips/sgi-ip27/Makefile3
-rw-r--r--arch/mips/sgi-ip27/ip27-hubio.c4
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c39
-rw-r--r--arch/mips/sgi-ip27/ip27-irq-pci.c266
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c357
-rw-r--r--arch/mips/sgi-ip27/ip27-irqno.c48
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c34
-rw-r--r--arch/mips/sgi-ip27/ip27-nmi.c64
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c5
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c42
-rw-r--r--arch/mips/sgi-ip27/ip27-xtalk.c13
-rw-r--r--drivers/soc/lantiq/Makefile1
-rw-r--r--drivers/soc/lantiq/gphy.c224
-rw-r--r--include/dt-bindings/clock/ath79-clk.h4
119 files changed, 1610 insertions, 4615 deletions
diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt
deleted file mode 100644
index a0c19bd1ce66..000000000000
--- a/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt
+++ /dev/null
@@ -1,36 +0,0 @@
1Lantiq XWAY SoC GPHY binding
2============================
3
4This binding describes a software-defined ethernet PHY, provided by the RCU
5module on newer Lantiq XWAY SoCs (xRX200 and newer).
6
7-------------------------------------------------------------------------------
8Required properties:
9- compatible : Should be one of
10 "lantiq,xrx200a1x-gphy"
11 "lantiq,xrx200a2x-gphy"
12 "lantiq,xrx300-gphy"
13 "lantiq,xrx330-gphy"
14- reg : Addrress of the GPHY FW load address register
15- resets : Must reference the RCU GPHY reset bit
16- reset-names : One entry, value must be "gphy" or optional "gphy2"
17- clocks : A reference to the (PMU) GPHY clock gate
18
19Optional properties:
20- lantiq,gphy-mode : GPHY_MODE_GE (default) or GPHY_MODE_FE as defined in
21 <dt-bindings/mips/lantiq_xway_gphy.h>
22
23
24-------------------------------------------------------------------------------
25Example for the GPHys on the xRX200 SoCs:
26
27#include <dt-bindings/mips/lantiq_rcu_gphy.h>
28 gphy0: gphy@20 {
29 compatible = "lantiq,xrx200a2x-gphy";
30 reg = <0x20 0x4>;
31
32 resets = <&reset0 31 30>, <&reset1 7 7>;
33 reset-names = "gphy", "gphy2";
34 clocks = <&pmu0 XRX200_PMU_GATE_GPHY>;
35 lantiq,gphy-mode = <GPHY_MODE_GE>;
36 };
diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt
index 7f0822b4beae..58d51f480c9e 100644
--- a/Documentation/devicetree/bindings/mips/lantiq/rcu.txt
+++ b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt
@@ -26,24 +26,6 @@ Example of the RCU bindings on a xRX200 SoC:
26 ranges = <0x0 0x203000 0x100>; 26 ranges = <0x0 0x203000 0x100>;
27 big-endian; 27 big-endian;
28 28
29 gphy0: gphy@20 {
30 compatible = "lantiq,xrx200a2x-gphy";
31 reg = <0x20 0x4>;
32
33 resets = <&reset0 31 30>, <&reset1 7 7>;
34 reset-names = "gphy", "gphy2";
35 lantiq,gphy-mode = <GPHY_MODE_GE>;
36 };
37
38 gphy1: gphy@68 {
39 compatible = "lantiq,xrx200a2x-gphy";
40 reg = <0x68 0x4>;
41
42 resets = <&reset0 29 28>, <&reset1 6 6>;
43 reset-names = "gphy", "gphy2";
44 lantiq,gphy-mode = <GPHY_MODE_GE>;
45 };
46
47 reset0: reset-controller@10 { 29 reset0: reset-controller@10 {
48 compatible = "lantiq,xrx200-reset"; 30 compatible = "lantiq,xrx200-reset";
49 reg = <0x10 4>, <0x14 4>; 31 reg = <0x10 4>, <0x14 4>;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a84c24d894aa..9036ef9ec74a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -206,7 +206,6 @@ config ATH79
206 select COMMON_CLK 206 select COMMON_CLK
207 select CLKDEV_LOOKUP 207 select CLKDEV_LOOKUP
208 select IRQ_MIPS_CPU 208 select IRQ_MIPS_CPU
209 select MIPS_MACHINE
210 select SYS_HAS_CPU_MIPS32_R2 209 select SYS_HAS_CPU_MIPS32_R2
211 select SYS_HAS_EARLY_PRINTK 210 select SYS_HAS_EARLY_PRINTK
212 select SYS_SUPPORTS_32BIT_KERNEL 211 select SYS_SUPPORTS_32BIT_KERNEL
@@ -391,7 +390,7 @@ config MACH_INGENIC
391 select GPIOLIB 390 select GPIOLIB
392 select COMMON_CLK 391 select COMMON_CLK
393 select GENERIC_IRQ_CHIP 392 select GENERIC_IRQ_CHIP
394 select BUILTIN_DTB 393 select BUILTIN_DTB if MIPS_NO_APPENDED_DTB
395 select USE_OF 394 select USE_OF
396 select LIBFDT 395 select LIBFDT
397 396
@@ -676,6 +675,7 @@ config SGI_IP27
676 select DEFAULT_SGI_PARTITION 675 select DEFAULT_SGI_PARTITION
677 select SYS_HAS_EARLY_PRINTK 676 select SYS_HAS_EARLY_PRINTK
678 select HAVE_PCI 677 select HAVE_PCI
678 select IRQ_MIPS_CPU
679 select NR_CPUS_DEFAULT_64 679 select NR_CPUS_DEFAULT_64
680 select SYS_HAS_CPU_R10000 680 select SYS_HAS_CPU_R10000
681 select SYS_SUPPORTS_64BIT_KERNEL 681 select SYS_SUPPORTS_64BIT_KERNEL
@@ -1124,7 +1124,6 @@ config DMA_NONCOHERENT
1124 bool 1124 bool
1125 select ARCH_HAS_DMA_MMAP_PGPROT 1125 select ARCH_HAS_DMA_MMAP_PGPROT
1126 select ARCH_HAS_SYNC_DMA_FOR_DEVICE 1126 select ARCH_HAS_SYNC_DMA_FOR_DEVICE
1127 select ARCH_HAS_SYNC_DMA_FOR_CPU
1128 select NEED_DMA_MAP_STATE 1127 select NEED_DMA_MAP_STATE
1129 select ARCH_HAS_DMA_COHERENT_TO_PFN 1128 select ARCH_HAS_DMA_COHERENT_TO_PFN
1130 select DMA_NONCOHERENT_CACHE_SYNC 1129 select DMA_NONCOHERENT_CACHE_SYNC
@@ -1556,6 +1555,7 @@ config CPU_MIPS64_R6
1556 select CPU_SUPPORTS_32BIT_KERNEL 1555 select CPU_SUPPORTS_32BIT_KERNEL
1557 select CPU_SUPPORTS_64BIT_KERNEL 1556 select CPU_SUPPORTS_64BIT_KERNEL
1558 select CPU_SUPPORTS_HIGHMEM 1557 select CPU_SUPPORTS_HIGHMEM
1558 select CPU_SUPPORTS_HUGEPAGES
1559 select CPU_SUPPORTS_MSA 1559 select CPU_SUPPORTS_MSA
1560 select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 1560 select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32
1561 select HAVE_KVM 1561 select HAVE_KVM
@@ -1881,7 +1881,7 @@ config CPU_LOONGSON2
1881config CPU_LOONGSON1 1881config CPU_LOONGSON1
1882 bool 1882 bool
1883 select CPU_MIPS32 1883 select CPU_MIPS32
1884 select CPU_MIPSR1 1884 select CPU_MIPSR2
1885 select CPU_HAS_PREFETCH 1885 select CPU_HAS_PREFETCH
1886 select CPU_HAS_LOAD_STORE_LR 1886 select CPU_HAS_LOAD_STORE_LR
1887 select CPU_SUPPORTS_32BIT_KERNEL 1887 select CPU_SUPPORTS_32BIT_KERNEL
@@ -1943,9 +1943,11 @@ config SYS_HAS_CPU_MIPS32_R3_5
1943 1943
1944config SYS_HAS_CPU_MIPS32_R5 1944config SYS_HAS_CPU_MIPS32_R5
1945 bool 1945 bool
1946 select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
1946 1947
1947config SYS_HAS_CPU_MIPS32_R6 1948config SYS_HAS_CPU_MIPS32_R6
1948 bool 1949 bool
1950 select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
1949 1951
1950config SYS_HAS_CPU_MIPS64_R1 1952config SYS_HAS_CPU_MIPS64_R1
1951 bool 1953 bool
@@ -1955,6 +1957,7 @@ config SYS_HAS_CPU_MIPS64_R2
1955 1957
1956config SYS_HAS_CPU_MIPS64_R6 1958config SYS_HAS_CPU_MIPS64_R6
1957 bool 1959 bool
1960 select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
1958 1961
1959config SYS_HAS_CPU_R3000 1962config SYS_HAS_CPU_R3000
1960 bool 1963 bool
@@ -1991,6 +1994,7 @@ config SYS_HAS_CPU_R8000
1991 1994
1992config SYS_HAS_CPU_R10000 1995config SYS_HAS_CPU_R10000
1993 bool 1996 bool
1997 select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
1994 1998
1995config SYS_HAS_CPU_RM7000 1999config SYS_HAS_CPU_RM7000
1996 bool 2000 bool
@@ -2019,6 +2023,7 @@ config SYS_HAS_CPU_BMIPS4380
2019config SYS_HAS_CPU_BMIPS5000 2023config SYS_HAS_CPU_BMIPS5000
2020 bool 2024 bool
2021 select SYS_HAS_CPU_BMIPS 2025 select SYS_HAS_CPU_BMIPS
2026 select ARCH_HAS_SYNC_DMA_FOR_CPU
2022 2027
2023config SYS_HAS_CPU_XLR 2028config SYS_HAS_CPU_XLR
2024 bool 2029 bool
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 5b174c3d0de3..8f4486c4415b 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -233,6 +233,8 @@ toolchain-crc := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mcrc)
233cflags-$(toolchain-crc) += -DTOOLCHAIN_SUPPORTS_CRC 233cflags-$(toolchain-crc) += -DTOOLCHAIN_SUPPORTS_CRC
234toolchain-dsp := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mdsp) 234toolchain-dsp := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mdsp)
235cflags-$(toolchain-dsp) += -DTOOLCHAIN_SUPPORTS_DSP 235cflags-$(toolchain-dsp) += -DTOOLCHAIN_SUPPORTS_DSP
236toolchain-ginv := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mginv)
237cflags-$(toolchain-ginv) += -DTOOLCHAIN_SUPPORTS_GINV
236 238
237# 239#
238# Firmware support 240# Firmware support
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 191c3910eac5..7367416642cb 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -1,79 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2if ATH79 2if ATH79
3 3
4menu "Atheros AR71XX/AR724X/AR913X machine selection"
5
6config ATH79_MACH_AP121
7 bool "Atheros AP121 reference board"
8 select SOC_AR933X
9 select ATH79_DEV_GPIO_BUTTONS
10 select ATH79_DEV_LEDS_GPIO
11 select ATH79_DEV_SPI
12 select ATH79_DEV_USB
13 select ATH79_DEV_WMAC
14 help
15 Say 'Y' here if you want your kernel to support the
16 Atheros AP121 reference board.
17
18config ATH79_MACH_AP136
19 bool "Atheros AP136 reference board"
20 select SOC_QCA955X
21 select ATH79_DEV_GPIO_BUTTONS
22 select ATH79_DEV_LEDS_GPIO
23 select ATH79_DEV_SPI
24 select ATH79_DEV_USB
25 select ATH79_DEV_WMAC
26 help
27 Say 'Y' here if you want your kernel to support the
28 Atheros AP136 reference board.
29
30config ATH79_MACH_AP81
31 bool "Atheros AP81 reference board"
32 select SOC_AR913X
33 select ATH79_DEV_GPIO_BUTTONS
34 select ATH79_DEV_LEDS_GPIO
35 select ATH79_DEV_SPI
36 select ATH79_DEV_USB
37 select ATH79_DEV_WMAC
38 help
39 Say 'Y' here if you want your kernel to support the
40 Atheros AP81 reference board.
41
42config ATH79_MACH_DB120
43 bool "Atheros DB120 reference board"
44 select SOC_AR934X
45 select ATH79_DEV_GPIO_BUTTONS
46 select ATH79_DEV_LEDS_GPIO
47 select ATH79_DEV_SPI
48 select ATH79_DEV_USB
49 select ATH79_DEV_WMAC
50 help
51 Say 'Y' here if you want your kernel to support the
52 Atheros DB120 reference board.
53
54config ATH79_MACH_PB44
55 bool "Atheros PB44 reference board"
56 select SOC_AR71XX
57 select ATH79_DEV_GPIO_BUTTONS
58 select ATH79_DEV_LEDS_GPIO
59 select ATH79_DEV_SPI
60 select ATH79_DEV_USB
61 help
62 Say 'Y' here if you want your kernel to support the
63 Atheros PB44 reference board.
64
65config ATH79_MACH_UBNT_XM
66 bool "Ubiquiti Networks XM (rev 1.0) board"
67 select SOC_AR724X
68 select ATH79_DEV_GPIO_BUTTONS
69 select ATH79_DEV_LEDS_GPIO
70 select ATH79_DEV_SPI
71 help
72 Say 'Y' here if you want your kernel to support the
73 Ubiquiti Networks XM (rev 1.0) board.
74
75endmenu
76
77config SOC_AR71XX 4config SOC_AR71XX
78 select HAVE_PCI 5 select HAVE_PCI
79 def_bool n 6 def_bool n
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index fcc382cfc770..e18d9a2ecf62 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -8,27 +8,6 @@
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
9# by the Free Software Foundation. 9# by the Free Software Foundation.
10 10
11obj-y := prom.o setup.o irq.o common.o clock.o 11obj-y := prom.o setup.o common.o clock.o
12 12
13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
14obj-$(CONFIG_PCI) += pci.o
15
16#
17# Devices
18#
19obj-y += dev-common.o
20obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
21obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
22obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o
23obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o
24obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o
25
26#
27# Machines
28#
29obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
30obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o
31obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
32obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o
33obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
34obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index cf9158e3c2d9..d4ca97e2ec6c 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -26,7 +26,6 @@
26#include <asm/mach-ath79/ath79.h> 26#include <asm/mach-ath79/ath79.h>
27#include <asm/mach-ath79/ar71xx_regs.h> 27#include <asm/mach-ath79/ar71xx_regs.h>
28#include "common.h" 28#include "common.h"
29#include "machtypes.h"
30 29
31#define AR71XX_BASE_FREQ 40000000 30#define AR71XX_BASE_FREQ 40000000
32#define AR724X_BASE_FREQ 40000000 31#define AR724X_BASE_FREQ 40000000
@@ -37,24 +36,63 @@ static struct clk_onecell_data clk_data = {
37 .clk_num = ARRAY_SIZE(clks), 36 .clk_num = ARRAY_SIZE(clks),
38}; 37};
39 38
40static struct clk *__init ath79_add_sys_clkdev( 39static const char * const clk_names[ATH79_CLK_END] = {
41 const char *id, unsigned long rate) 40 [ATH79_CLK_CPU] = "cpu",
41 [ATH79_CLK_DDR] = "ddr",
42 [ATH79_CLK_AHB] = "ahb",
43 [ATH79_CLK_REF] = "ref",
44 [ATH79_CLK_MDIO] = "mdio",
45};
46
47static const char * __init ath79_clk_name(int type)
42{ 48{
43 struct clk *clk; 49 BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]);
44 int err; 50 return clk_names[type];
51}
45 52
46 clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate); 53static void __init __ath79_set_clk(int type, const char *name, struct clk *clk)
54{
47 if (IS_ERR(clk)) 55 if (IS_ERR(clk))
48 panic("failed to allocate %s clock structure", id); 56 panic("failed to allocate %s clock structure", clk_names[type]);
49 57
50 err = clk_register_clkdev(clk, id, NULL); 58 clks[type] = clk;
51 if (err) 59 clk_register_clkdev(clk, name, NULL);
52 panic("unable to register %s clock device", id); 60}
53 61
62static struct clk * __init ath79_set_clk(int type, unsigned long rate)
63{
64 const char *name = ath79_clk_name(type);
65 struct clk *clk;
66
67 clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate);
68 __ath79_set_clk(type, name, clk);
54 return clk; 69 return clk;
55} 70}
56 71
57static void __init ar71xx_clocks_init(void) 72static struct clk * __init ath79_set_ff_clk(int type, const char *parent,
73 unsigned int mult, unsigned int div)
74{
75 const char *name = ath79_clk_name(type);
76 struct clk *clk;
77
78 clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div);
79 __ath79_set_clk(type, name, clk);
80 return clk;
81}
82
83static unsigned long __init ath79_setup_ref_clk(unsigned long rate)
84{
85 struct clk *clk = clks[ATH79_CLK_REF];
86
87 if (clk)
88 rate = clk_get_rate(clk);
89 else
90 clk = ath79_set_clk(ATH79_CLK_REF, rate);
91
92 return rate;
93}
94
95static void __init ar71xx_clocks_init(void __iomem *pll_base)
58{ 96{
59 unsigned long ref_rate; 97 unsigned long ref_rate;
60 unsigned long cpu_rate; 98 unsigned long cpu_rate;
@@ -64,9 +102,9 @@ static void __init ar71xx_clocks_init(void)
64 u32 freq; 102 u32 freq;
65 u32 div; 103 u32 div;
66 104
67 ref_rate = AR71XX_BASE_FREQ; 105 ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ);
68 106
69 pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); 107 pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG);
70 108
71 div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; 109 div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1;
72 freq = div * ref_rate; 110 freq = div * ref_rate;
@@ -80,31 +118,17 @@ static void __init ar71xx_clocks_init(void)
80 div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; 118 div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
81 ahb_rate = cpu_rate / div; 119 ahb_rate = cpu_rate / div;
82 120
83 ath79_add_sys_clkdev("ref", ref_rate); 121 ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
84 clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); 122 ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
85 clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); 123 ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
86 clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
87
88 clk_add_alias("wdt", NULL, "ahb", NULL);
89 clk_add_alias("uart", NULL, "ahb", NULL);
90} 124}
91 125
92static struct clk * __init ath79_reg_ffclk(const char *name, 126static void __init ar724x_clocks_init(void __iomem *pll_base)
93 const char *parent_name, unsigned int mult, unsigned int div)
94{ 127{
95 struct clk *clk;
96
97 clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div);
98 if (IS_ERR(clk))
99 panic("failed to allocate %s clock structure", name);
100
101 return clk;
102}
103
104static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base)
105{
106 u32 pll;
107 u32 mult, div, ddr_div, ahb_div; 128 u32 mult, div, ddr_div, ahb_div;
129 u32 pll;
130
131 ath79_setup_ref_clk(AR71XX_BASE_FREQ);
108 132
109 pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); 133 pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
110 134
@@ -114,30 +138,14 @@ static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base)
114 ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 138 ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
115 ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 139 ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
116 140
117 clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div); 141 ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div);
118 clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div); 142 ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div);
119 clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div); 143 ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div);
120}
121
122static void __init ar724x_clocks_init(void)
123{
124 struct clk *ref_clk;
125
126 ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ);
127
128 ar724x_clk_init(ref_clk, ath79_pll_base);
129
130 /* just make happy plat_time_init() from arch/mips/ath79/setup.c */
131 clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL);
132 clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL);
133 clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL);
134
135 clk_add_alias("wdt", NULL, "ahb", NULL);
136 clk_add_alias("uart", NULL, "ahb", NULL);
137} 144}
138 145
139static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) 146static void __init ar933x_clocks_init(void __iomem *pll_base)
140{ 147{
148 unsigned long ref_rate;
141 u32 clock_ctrl; 149 u32 clock_ctrl;
142 u32 ref_div; 150 u32 ref_div;
143 u32 ninit_mul; 151 u32 ninit_mul;
@@ -146,6 +154,15 @@ static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base)
146 u32 cpu_div; 154 u32 cpu_div;
147 u32 ddr_div; 155 u32 ddr_div;
148 u32 ahb_div; 156 u32 ahb_div;
157 u32 t;
158
159 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
160 if (t & AR933X_BOOTSTRAP_REF_CLK_40)
161 ref_rate = (40 * 1000 * 1000);
162 else
163 ref_rate = (25 * 1000 * 1000);
164
165 ath79_setup_ref_clk(ref_rate);
149 166
150 clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); 167 clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG);
151 if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 168 if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
@@ -186,37 +203,12 @@ static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base)
186 AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 203 AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
187 } 204 }
188 205
189 clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", 206 ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul,
190 ninit_mul, ref_div * out_div * cpu_div); 207 ref_div * out_div * cpu_div);
191 clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", 208 ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul,
192 ninit_mul, ref_div * out_div * ddr_div); 209 ref_div * out_div * ddr_div);
193 clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", 210 ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul,
194 ninit_mul, ref_div * out_div * ahb_div); 211 ref_div * out_div * ahb_div);
195}
196
197static void __init ar933x_clocks_init(void)
198{
199 struct clk *ref_clk;
200 unsigned long ref_rate;
201 u32 t;
202
203 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
204 if (t & AR933X_BOOTSTRAP_REF_CLK_40)
205 ref_rate = (40 * 1000 * 1000);
206 else
207 ref_rate = (25 * 1000 * 1000);
208
209 ref_clk = ath79_add_sys_clkdev("ref", ref_rate);
210
211 ar9330_clk_init(ref_clk, ath79_pll_base);
212
213 /* just make happy plat_time_init() from arch/mips/ath79/setup.c */
214 clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL);
215 clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL);
216 clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL);
217
218 clk_add_alias("wdt", NULL, "ahb", NULL);
219 clk_add_alias("uart", NULL, "ref", NULL);
220} 212}
221 213
222static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, 214static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
@@ -239,7 +231,7 @@ static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
239 return ret; 231 return ret;
240} 232}
241 233
242static void __init ar934x_clocks_init(void) 234static void __init ar934x_clocks_init(void __iomem *pll_base)
243{ 235{
244 unsigned long ref_rate; 236 unsigned long ref_rate;
245 unsigned long cpu_rate; 237 unsigned long cpu_rate;
@@ -258,6 +250,8 @@ static void __init ar934x_clocks_init(void)
258 else 250 else
259 ref_rate = 25 * 1000 * 1000; 251 ref_rate = 25 * 1000 * 1000;
260 252
253 ref_rate = ath79_setup_ref_clk(ref_rate);
254
261 pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); 255 pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
262 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 256 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
263 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 257 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
@@ -270,7 +264,7 @@ static void __init ar934x_clocks_init(void)
270 AR934X_SRIF_DPLL1_REFDIV_MASK; 264 AR934X_SRIF_DPLL1_REFDIV_MASK;
271 frac = 1 << 18; 265 frac = 1 << 18;
272 } else { 266 } else {
273 pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); 267 pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG);
274 out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 268 out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
275 AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; 269 AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
276 ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 270 ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
@@ -297,7 +291,7 @@ static void __init ar934x_clocks_init(void)
297 AR934X_SRIF_DPLL1_REFDIV_MASK; 291 AR934X_SRIF_DPLL1_REFDIV_MASK;
298 frac = 1 << 18; 292 frac = 1 << 18;
299 } else { 293 } else {
300 pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); 294 pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG);
301 out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 295 out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
302 AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; 296 AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
303 ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 297 ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
@@ -312,7 +306,7 @@ static void __init ar934x_clocks_init(void)
312 ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 306 ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
313 nfrac, frac, out_div); 307 nfrac, frac, out_div);
314 308
315 clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); 309 clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
316 310
317 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & 311 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
318 AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; 312 AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
@@ -344,18 +338,18 @@ static void __init ar934x_clocks_init(void)
344 else 338 else
345 ahb_rate = cpu_pll / (postdiv + 1); 339 ahb_rate = cpu_pll / (postdiv + 1);
346 340
347 ath79_add_sys_clkdev("ref", ref_rate); 341 ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
348 clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); 342 ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
349 clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); 343 ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
350 clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
351 344
352 clk_add_alias("wdt", NULL, "ref", NULL); 345 clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
353 clk_add_alias("uart", NULL, "ref", NULL); 346 if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL)
347 ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000);
354 348
355 iounmap(dpll_base); 349 iounmap(dpll_base);
356} 350}
357 351
358static void __init qca953x_clocks_init(void) 352static void __init qca953x_clocks_init(void __iomem *pll_base)
359{ 353{
360 unsigned long ref_rate; 354 unsigned long ref_rate;
361 unsigned long cpu_rate; 355 unsigned long cpu_rate;
@@ -371,7 +365,9 @@ static void __init qca953x_clocks_init(void)
371 else 365 else
372 ref_rate = 25 * 1000 * 1000; 366 ref_rate = 25 * 1000 * 1000;
373 367
374 pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG); 368 ref_rate = ath79_setup_ref_clk(ref_rate);
369
370 pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG);
375 out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 371 out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
376 QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; 372 QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
377 ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 373 ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
@@ -385,7 +381,7 @@ static void __init qca953x_clocks_init(void)
385 cpu_pll += frac * (ref_rate >> 6) / ref_div; 381 cpu_pll += frac * (ref_rate >> 6) / ref_div;
386 cpu_pll /= (1 << out_div); 382 cpu_pll /= (1 << out_div);
387 383
388 pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG); 384 pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG);
389 out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 385 out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
390 QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; 386 QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
391 ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 387 ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
@@ -399,7 +395,7 @@ static void __init qca953x_clocks_init(void)
399 ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); 395 ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
400 ddr_pll /= (1 << out_div); 396 ddr_pll /= (1 << out_div);
401 397
402 clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG); 398 clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG);
403 399
404 postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 400 postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
405 QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 401 QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
@@ -431,16 +427,12 @@ static void __init qca953x_clocks_init(void)
431 else 427 else
432 ahb_rate = cpu_pll / (postdiv + 1); 428 ahb_rate = cpu_pll / (postdiv + 1);
433 429
434 ath79_add_sys_clkdev("ref", ref_rate); 430 ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
435 ath79_add_sys_clkdev("cpu", cpu_rate); 431 ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
436 ath79_add_sys_clkdev("ddr", ddr_rate); 432 ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
437 ath79_add_sys_clkdev("ahb", ahb_rate);
438
439 clk_add_alias("wdt", NULL, "ref", NULL);
440 clk_add_alias("uart", NULL, "ref", NULL);
441} 433}
442 434
443static void __init qca955x_clocks_init(void) 435static void __init qca955x_clocks_init(void __iomem *pll_base)
444{ 436{
445 unsigned long ref_rate; 437 unsigned long ref_rate;
446 unsigned long cpu_rate; 438 unsigned long cpu_rate;
@@ -456,7 +448,9 @@ static void __init qca955x_clocks_init(void)
456 else 448 else
457 ref_rate = 25 * 1000 * 1000; 449 ref_rate = 25 * 1000 * 1000;
458 450
459 pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG); 451 ref_rate = ath79_setup_ref_clk(ref_rate);
452
453 pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG);
460 out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 454 out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
461 QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; 455 QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK;
462 ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 456 ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
@@ -470,7 +464,7 @@ static void __init qca955x_clocks_init(void)
470 cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); 464 cpu_pll += frac * ref_rate / (ref_div * (1 << 6));
471 cpu_pll /= (1 << out_div); 465 cpu_pll /= (1 << out_div);
472 466
473 pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG); 467 pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG);
474 out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 468 out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
475 QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; 469 QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK;
476 ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 470 ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
@@ -484,7 +478,7 @@ static void __init qca955x_clocks_init(void)
484 ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); 478 ddr_pll += frac * ref_rate / (ref_div * (1 << 10));
485 ddr_pll /= (1 << out_div); 479 ddr_pll /= (1 << out_div);
486 480
487 clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG); 481 clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG);
488 482
489 postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 483 postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
490 QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 484 QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
@@ -516,16 +510,12 @@ static void __init qca955x_clocks_init(void)
516 else 510 else
517 ahb_rate = cpu_pll / (postdiv + 1); 511 ahb_rate = cpu_pll / (postdiv + 1);
518 512
519 ath79_add_sys_clkdev("ref", ref_rate); 513 ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
520 clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); 514 ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
521 clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); 515 ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
522 clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
523
524 clk_add_alias("wdt", NULL, "ref", NULL);
525 clk_add_alias("uart", NULL, "ref", NULL);
526} 516}
527 517
528static void __init qca956x_clocks_init(void) 518static void __init qca956x_clocks_init(void __iomem *pll_base)
529{ 519{
530 unsigned long ref_rate; 520 unsigned long ref_rate;
531 unsigned long cpu_rate; 521 unsigned long cpu_rate;
@@ -551,13 +541,15 @@ static void __init qca956x_clocks_init(void)
551 else 541 else
552 ref_rate = 25 * 1000 * 1000; 542 ref_rate = 25 * 1000 * 1000;
553 543
554 pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG); 544 ref_rate = ath79_setup_ref_clk(ref_rate);
545
546 pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG);
555 out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 547 out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
556 QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; 548 QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
557 ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 549 ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
558 QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; 550 QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
559 551
560 pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG); 552 pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG);
561 nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & 553 nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
562 QCA956X_PLL_CPU_CONFIG1_NINT_MASK; 554 QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
563 hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & 555 hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
@@ -570,12 +562,12 @@ static void __init qca956x_clocks_init(void)
570 cpu_pll += (hfrac >> 13) * ref_rate / ref_div; 562 cpu_pll += (hfrac >> 13) * ref_rate / ref_div;
571 cpu_pll /= (1 << out_div); 563 cpu_pll /= (1 << out_div);
572 564
573 pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG); 565 pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG);
574 out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 566 out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
575 QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; 567 QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
576 ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 568 ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
577 QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; 569 QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
578 pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG); 570 pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG);
579 nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & 571 nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
580 QCA956X_PLL_DDR_CONFIG1_NINT_MASK; 572 QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
581 hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & 573 hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
@@ -588,7 +580,7 @@ static void __init qca956x_clocks_init(void)
588 ddr_pll += (hfrac >> 13) * ref_rate / ref_div; 580 ddr_pll += (hfrac >> 13) * ref_rate / ref_div;
589 ddr_pll /= (1 << out_div); 581 ddr_pll /= (1 << out_div);
590 582
591 clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG); 583 clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG);
592 584
593 postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 585 postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
594 QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 586 QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
@@ -620,72 +612,19 @@ static void __init qca956x_clocks_init(void)
620 else 612 else
621 ahb_rate = cpu_pll / (postdiv + 1); 613 ahb_rate = cpu_pll / (postdiv + 1);
622 614
623 ath79_add_sys_clkdev("ref", ref_rate); 615 ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
624 ath79_add_sys_clkdev("cpu", cpu_rate); 616 ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
625 ath79_add_sys_clkdev("ddr", ddr_rate); 617 ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
626 ath79_add_sys_clkdev("ahb", ahb_rate);
627
628 clk_add_alias("wdt", NULL, "ref", NULL);
629 clk_add_alias("uart", NULL, "ref", NULL);
630}
631
632void __init ath79_clocks_init(void)
633{
634 if (soc_is_ar71xx())
635 ar71xx_clocks_init();
636 else if (soc_is_ar724x() || soc_is_ar913x())
637 ar724x_clocks_init();
638 else if (soc_is_ar933x())
639 ar933x_clocks_init();
640 else if (soc_is_ar934x())
641 ar934x_clocks_init();
642 else if (soc_is_qca953x())
643 qca953x_clocks_init();
644 else if (soc_is_qca955x())
645 qca955x_clocks_init();
646 else if (soc_is_qca956x() || soc_is_tp9343())
647 qca956x_clocks_init();
648 else
649 BUG();
650}
651
652unsigned long __init
653ath79_get_sys_clk_rate(const char *id)
654{
655 struct clk *clk;
656 unsigned long rate;
657
658 clk = clk_get(NULL, id);
659 if (IS_ERR(clk))
660 panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk));
661
662 rate = clk_get_rate(clk);
663 clk_put(clk);
664
665 return rate;
666} 618}
667 619
668#ifdef CONFIG_OF
669static void __init ath79_clocks_init_dt(struct device_node *np) 620static void __init ath79_clocks_init_dt(struct device_node *np)
670{ 621{
671 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
672}
673
674CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt);
675CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt);
676CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt);
677CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt);
678
679static void __init ath79_clocks_init_dt_ng(struct device_node *np)
680{
681 struct clk *ref_clk; 622 struct clk *ref_clk;
682 void __iomem *pll_base; 623 void __iomem *pll_base;
683 624
684 ref_clk = of_clk_get(np, 0); 625 ref_clk = of_clk_get(np, 0);
685 if (IS_ERR(ref_clk)) { 626 if (!IS_ERR(ref_clk))
686 pr_err("%pOF: of_clk_get failed\n", np); 627 clks[ATH79_CLK_REF] = ref_clk;
687 goto err;
688 }
689 628
690 pll_base = of_iomap(np, 0); 629 pll_base = of_iomap(np, 0);
691 if (!pll_base) { 630 if (!pll_base) {
@@ -693,14 +632,24 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np)
693 goto err_clk; 632 goto err_clk;
694 } 633 }
695 634
696 if (of_device_is_compatible(np, "qca,ar9130-pll")) 635 if (of_device_is_compatible(np, "qca,ar7100-pll"))
697 ar724x_clk_init(ref_clk, pll_base); 636 ar71xx_clocks_init(pll_base);
637 else if (of_device_is_compatible(np, "qca,ar7240-pll") ||
638 of_device_is_compatible(np, "qca,ar9130-pll"))
639 ar724x_clocks_init(pll_base);
698 else if (of_device_is_compatible(np, "qca,ar9330-pll")) 640 else if (of_device_is_compatible(np, "qca,ar9330-pll"))
699 ar9330_clk_init(ref_clk, pll_base); 641 ar933x_clocks_init(pll_base);
700 else { 642 else if (of_device_is_compatible(np, "qca,ar9340-pll"))
701 pr_err("%pOF: could not find any appropriate clk_init()\n", np); 643 ar934x_clocks_init(pll_base);
702 goto err_iounmap; 644 else if (of_device_is_compatible(np, "qca,qca9530-pll"))
703 } 645 qca953x_clocks_init(pll_base);
646 else if (of_device_is_compatible(np, "qca,qca9550-pll"))
647 qca955x_clocks_init(pll_base);
648 else if (of_device_is_compatible(np, "qca,qca9560-pll"))
649 qca956x_clocks_init(pll_base);
650
651 if (!clks[ATH79_CLK_MDIO])
652 clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF];
704 653
705 if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { 654 if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
706 pr_err("%pOF: could not register clk provider\n", np); 655 pr_err("%pOF: could not register clk provider\n", np);
@@ -714,10 +663,13 @@ err_iounmap:
714 663
715err_clk: 664err_clk:
716 clk_put(ref_clk); 665 clk_put(ref_clk);
717
718err:
719 return;
720} 666}
721CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng); 667
722CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng); 668CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt);
723#endif 669CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt);
670CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt);
671CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt);
672CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt);
673CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt);
674CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt);
675CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt);
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
index 870c6b2e97e8..25b96f59e8e8 100644
--- a/arch/mips/ath79/common.h
+++ b/arch/mips/ath79/common.h
@@ -19,11 +19,6 @@
19#define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024) 19#define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024)
20#define ATH79_MEM_SIZE_MAX (256 * 1024 * 1024) 20#define ATH79_MEM_SIZE_MAX (256 * 1024 * 1024)
21 21
22void ath79_clocks_init(void);
23unsigned long ath79_get_sys_clk_rate(const char *id);
24
25void ath79_ddr_ctrl_init(void); 22void ath79_ddr_ctrl_init(void);
26 23
27void ath79_gpio_init(void);
28
29#endif /* __ATH79_COMMON_H */ 24#endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
deleted file mode 100644
index 9d0172a4dc69..000000000000
--- a/arch/mips/ath79/dev-common.c
+++ /dev/null
@@ -1,159 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X common devices
3 *
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
7 * Parts of this file are based on Atheros' 2.6.15 BSP
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17#include <linux/platform_data/gpio-ath79.h>
18#include <linux/serial_8250.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21
22#include <asm/mach-ath79/ath79.h>
23#include <asm/mach-ath79/ar71xx_regs.h>
24#include "common.h"
25#include "dev-common.h"
26
27static struct resource ath79_uart_resources[] = {
28 {
29 .start = AR71XX_UART_BASE,
30 .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
31 .flags = IORESOURCE_MEM,
32 },
33};
34
35#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
36static struct plat_serial8250_port ath79_uart_data[] = {
37 {
38 .mapbase = AR71XX_UART_BASE,
39 .irq = ATH79_MISC_IRQ(3),
40 .flags = AR71XX_UART_FLAGS,
41 .iotype = UPIO_MEM32,
42 .regshift = 2,
43 }, {
44 /* terminating entry */
45 }
46};
47
48static struct platform_device ath79_uart_device = {
49 .name = "serial8250",
50 .id = PLAT8250_DEV_PLATFORM,
51 .resource = ath79_uart_resources,
52 .num_resources = ARRAY_SIZE(ath79_uart_resources),
53 .dev = {
54 .platform_data = ath79_uart_data
55 },
56};
57
58static struct resource ar933x_uart_resources[] = {
59 {
60 .start = AR933X_UART_BASE,
61 .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1,
62 .flags = IORESOURCE_MEM,
63 },
64 {
65 .start = ATH79_MISC_IRQ(3),
66 .end = ATH79_MISC_IRQ(3),
67 .flags = IORESOURCE_IRQ,
68 },
69};
70
71static struct platform_device ar933x_uart_device = {
72 .name = "ar933x-uart",
73 .id = -1,
74 .resource = ar933x_uart_resources,
75 .num_resources = ARRAY_SIZE(ar933x_uart_resources),
76};
77
78void __init ath79_register_uart(void)
79{
80 unsigned long uart_clk_rate;
81
82 uart_clk_rate = ath79_get_sys_clk_rate("uart");
83
84 if (soc_is_ar71xx() ||
85 soc_is_ar724x() ||
86 soc_is_ar913x() ||
87 soc_is_ar934x() ||
88 soc_is_qca955x()) {
89 ath79_uart_data[0].uartclk = uart_clk_rate;
90 platform_device_register(&ath79_uart_device);
91 } else if (soc_is_ar933x()) {
92 platform_device_register(&ar933x_uart_device);
93 } else {
94 BUG();
95 }
96}
97
98void __init ath79_register_wdt(void)
99{
100 struct resource res;
101
102 memset(&res, 0, sizeof(res));
103
104 res.flags = IORESOURCE_MEM;
105 res.start = AR71XX_RESET_BASE + AR71XX_RESET_REG_WDOG_CTRL;
106 res.end = res.start + 0x8 - 1;
107
108 platform_device_register_simple("ath79-wdt", -1, &res, 1);
109}
110
111static struct ath79_gpio_platform_data ath79_gpio_pdata;
112
113static struct resource ath79_gpio_resources[] = {
114 {
115 .flags = IORESOURCE_MEM,
116 .start = AR71XX_GPIO_BASE,
117 .end = AR71XX_GPIO_BASE + AR71XX_GPIO_SIZE - 1,
118 },
119 {
120 .start = ATH79_MISC_IRQ(2),
121 .end = ATH79_MISC_IRQ(2),
122 .flags = IORESOURCE_IRQ,
123 },
124};
125
126static struct platform_device ath79_gpio_device = {
127 .name = "ath79-gpio",
128 .id = -1,
129 .resource = ath79_gpio_resources,
130 .num_resources = ARRAY_SIZE(ath79_gpio_resources),
131 .dev = {
132 .platform_data = &ath79_gpio_pdata
133 },
134};
135
136void __init ath79_gpio_init(void)
137{
138 if (soc_is_ar71xx()) {
139 ath79_gpio_pdata.ngpios = AR71XX_GPIO_COUNT;
140 } else if (soc_is_ar7240()) {
141 ath79_gpio_pdata.ngpios = AR7240_GPIO_COUNT;
142 } else if (soc_is_ar7241() || soc_is_ar7242()) {
143 ath79_gpio_pdata.ngpios = AR7241_GPIO_COUNT;
144 } else if (soc_is_ar913x()) {
145 ath79_gpio_pdata.ngpios = AR913X_GPIO_COUNT;
146 } else if (soc_is_ar933x()) {
147 ath79_gpio_pdata.ngpios = AR933X_GPIO_COUNT;
148 } else if (soc_is_ar934x()) {
149 ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT;
150 ath79_gpio_pdata.oe_inverted = 1;
151 } else if (soc_is_qca955x()) {
152 ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT;
153 ath79_gpio_pdata.oe_inverted = 1;
154 } else {
155 BUG();
156 }
157
158 platform_device_register(&ath79_gpio_device);
159}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
deleted file mode 100644
index 0f514e1affce..000000000000
--- a/arch/mips/ath79/dev-common.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X common devices
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#ifndef _ATH79_DEV_COMMON_H
13#define _ATH79_DEV_COMMON_H
14
15void ath79_register_uart(void);
16void ath79_register_wdt(void);
17
18#endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c
deleted file mode 100644
index 366b35fb164d..000000000000
--- a/arch/mips/ath79/dev-gpio-buttons.c
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X GPIO button support
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#include "linux/init.h"
13#include "linux/slab.h"
14#include <linux/platform_device.h>
15
16#include "dev-gpio-buttons.h"
17
18void __init ath79_register_gpio_keys_polled(int id,
19 unsigned poll_interval,
20 unsigned nbuttons,
21 struct gpio_keys_button *buttons)
22{
23 struct platform_device *pdev;
24 struct gpio_keys_platform_data pdata;
25 struct gpio_keys_button *p;
26 int err;
27
28 p = kmemdup(buttons, nbuttons * sizeof(*p), GFP_KERNEL);
29 if (!p)
30 return;
31
32 pdev = platform_device_alloc("gpio-keys-polled", id);
33 if (!pdev)
34 goto err_free_buttons;
35
36 memset(&pdata, 0, sizeof(pdata));
37 pdata.poll_interval = poll_interval;
38 pdata.nbuttons = nbuttons;
39 pdata.buttons = p;
40
41 err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
42 if (err)
43 goto err_put_pdev;
44
45 err = platform_device_add(pdev);
46 if (err)
47 goto err_put_pdev;
48
49 return;
50
51err_put_pdev:
52 platform_device_put(pdev);
53
54err_free_buttons:
55 kfree(p);
56}
diff --git a/arch/mips/ath79/dev-gpio-buttons.h b/arch/mips/ath79/dev-gpio-buttons.h
deleted file mode 100644
index 481847ac1cba..000000000000
--- a/arch/mips/ath79/dev-gpio-buttons.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X GPIO button support
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#ifndef _ATH79_DEV_GPIO_BUTTONS_H
13#define _ATH79_DEV_GPIO_BUTTONS_H
14
15#include <linux/input.h>
16#include <linux/gpio_keys.h>
17
18void ath79_register_gpio_keys_polled(int id,
19 unsigned poll_interval,
20 unsigned nbuttons,
21 struct gpio_keys_button *buttons);
22
23#endif /* _ATH79_DEV_GPIO_BUTTONS_H */
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c
deleted file mode 100644
index dcb1debcefb8..000000000000
--- a/arch/mips/ath79/dev-leds-gpio.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/platform_device.h>
15
16#include "dev-leds-gpio.h"
17
18void __init ath79_register_leds_gpio(int id,
19 unsigned num_leds,
20 struct gpio_led *leds)
21{
22 struct platform_device *pdev;
23 struct gpio_led_platform_data pdata;
24 struct gpio_led *p;
25 int err;
26
27 p = kmemdup(leds, num_leds * sizeof(*p), GFP_KERNEL);
28 if (!p)
29 return;
30
31 pdev = platform_device_alloc("leds-gpio", id);
32 if (!pdev)
33 goto err_free_leds;
34
35 memset(&pdata, 0, sizeof(pdata));
36 pdata.num_leds = num_leds;
37 pdata.leds = p;
38
39 err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
40 if (err)
41 goto err_put_pdev;
42
43 err = platform_device_add(pdev);
44 if (err)
45 goto err_put_pdev;
46
47 return;
48
49err_put_pdev:
50 platform_device_put(pdev);
51
52err_free_leds:
53 kfree(p);
54}
diff --git a/arch/mips/ath79/dev-leds-gpio.h b/arch/mips/ath79/dev-leds-gpio.h
deleted file mode 100644
index 6e5d8851ebcf..000000000000
--- a/arch/mips/ath79/dev-leds-gpio.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#ifndef _ATH79_DEV_LEDS_GPIO_H
13#define _ATH79_DEV_LEDS_GPIO_H
14
15#include <linux/leds.h>
16
17void ath79_register_leds_gpio(int id,
18 unsigned num_leds,
19 struct gpio_led *leds);
20
21#endif /* _ATH79_DEV_LEDS_GPIO_H */
diff --git a/arch/mips/ath79/dev-spi.c b/arch/mips/ath79/dev-spi.c
deleted file mode 100644
index aa30163efbfd..000000000000
--- a/arch/mips/ath79/dev-spi.c
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X SPI controller device
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#include <linux/platform_device.h>
13#include <asm/mach-ath79/ar71xx_regs.h>
14#include "dev-spi.h"
15
16static struct resource ath79_spi_resources[] = {
17 {
18 .start = AR71XX_SPI_BASE,
19 .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
20 .flags = IORESOURCE_MEM,
21 },
22};
23
24static struct platform_device ath79_spi_device = {
25 .name = "ath79-spi",
26 .id = -1,
27 .resource = ath79_spi_resources,
28 .num_resources = ARRAY_SIZE(ath79_spi_resources),
29};
30
31void __init ath79_register_spi(struct ath79_spi_platform_data *pdata,
32 struct spi_board_info const *info,
33 unsigned n)
34{
35 spi_register_board_info(info, n);
36 ath79_spi_device.dev.platform_data = pdata;
37 platform_device_register(&ath79_spi_device);
38}
diff --git a/arch/mips/ath79/dev-spi.h b/arch/mips/ath79/dev-spi.h
deleted file mode 100644
index 6e15bc8651be..000000000000
--- a/arch/mips/ath79/dev-spi.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X SPI controller device
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#ifndef _ATH79_DEV_SPI_H
13#define _ATH79_DEV_SPI_H
14
15#include <linux/spi/spi.h>
16#include <linux/platform_data/spi-ath79.h>
17
18void ath79_register_spi(struct ath79_spi_platform_data *pdata,
19 struct spi_board_info const *info,
20 unsigned n);
21
22#endif /* _ATH79_DEV_SPI_H */
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
deleted file mode 100644
index 8227265bcc2d..000000000000
--- a/arch/mips/ath79/dev-usb.c
+++ /dev/null
@@ -1,242 +0,0 @@
1/*
2 * Atheros AR7XXX/AR9XXX USB Host Controller device
3 *
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
7 * Parts of this file are based on Atheros' 2.6.15 BSP
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/irq.h>
18#include <linux/dma-mapping.h>
19#include <linux/platform_device.h>
20#include <linux/usb/ehci_pdriver.h>
21#include <linux/usb/ohci_pdriver.h>
22
23#include <asm/mach-ath79/ath79.h>
24#include <asm/mach-ath79/ar71xx_regs.h>
25#include "common.h"
26#include "dev-usb.h"
27
28static u64 ath79_usb_dmamask = DMA_BIT_MASK(32);
29
30static struct usb_ohci_pdata ath79_ohci_pdata = {
31};
32
33static struct usb_ehci_pdata ath79_ehci_pdata_v1 = {
34 .has_synopsys_hc_bug = 1,
35};
36
37static struct usb_ehci_pdata ath79_ehci_pdata_v2 = {
38 .caps_offset = 0x100,
39 .has_tt = 1,
40};
41
42static void __init ath79_usb_register(const char *name, int id,
43 unsigned long base, unsigned long size,
44 int irq, const void *data,
45 size_t data_size)
46{
47 struct resource res[2];
48 struct platform_device *pdev;
49
50 memset(res, 0, sizeof(res));
51
52 res[0].flags = IORESOURCE_MEM;
53 res[0].start = base;
54 res[0].end = base + size - 1;
55
56 res[1].flags = IORESOURCE_IRQ;
57 res[1].start = irq;
58 res[1].end = irq;
59
60 pdev = platform_device_register_resndata(NULL, name, id,
61 res, ARRAY_SIZE(res),
62 data, data_size);
63
64 if (IS_ERR(pdev)) {
65 pr_err("ath79: unable to register USB at %08lx, err=%d\n",
66 base, (int) PTR_ERR(pdev));
67 return;
68 }
69
70 pdev->dev.dma_mask = &ath79_usb_dmamask;
71 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
72}
73
74#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \
75 AR71XX_RESET_USB_PHY | \
76 AR71XX_RESET_USB_OHCI_DLL)
77
78static void __init ath79_usb_setup(void)
79{
80 void __iomem *usb_ctrl_base;
81
82 ath79_device_reset_set(AR71XX_USB_RESET_MASK);
83 mdelay(1000);
84 ath79_device_reset_clear(AR71XX_USB_RESET_MASK);
85
86 usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE);
87
88 /* Turning on the Buff and Desc swap bits */
89 __raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG);
90
91 /* WAR for HW bug. Here it adjusts the duration between two SOFS */
92 __raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
93
94 iounmap(usb_ctrl_base);
95
96 mdelay(900);
97
98 ath79_usb_register("ohci-platform", -1,
99 AR71XX_OHCI_BASE, AR71XX_OHCI_SIZE,
100 ATH79_MISC_IRQ(6),
101 &ath79_ohci_pdata, sizeof(ath79_ohci_pdata));
102
103 ath79_usb_register("ehci-platform", -1,
104 AR71XX_EHCI_BASE, AR71XX_EHCI_SIZE,
105 ATH79_CPU_IRQ(3),
106 &ath79_ehci_pdata_v1, sizeof(ath79_ehci_pdata_v1));
107}
108
109static void __init ar7240_usb_setup(void)
110{
111 void __iomem *usb_ctrl_base;
112
113 ath79_device_reset_clear(AR7240_RESET_OHCI_DLL);
114 ath79_device_reset_set(AR7240_RESET_USB_HOST);
115
116 mdelay(1000);
117
118 ath79_device_reset_set(AR7240_RESET_OHCI_DLL);
119 ath79_device_reset_clear(AR7240_RESET_USB_HOST);
120
121 usb_ctrl_base = ioremap(AR7240_USB_CTRL_BASE, AR7240_USB_CTRL_SIZE);
122
123 /* WAR for HW bug. Here it adjusts the duration between two SOFS */
124 __raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
125
126 iounmap(usb_ctrl_base);
127
128 ath79_usb_register("ohci-platform", -1,
129 AR7240_OHCI_BASE, AR7240_OHCI_SIZE,
130 ATH79_CPU_IRQ(3),
131 &ath79_ohci_pdata, sizeof(ath79_ohci_pdata));
132}
133
134static void __init ar724x_usb_setup(void)
135{
136 ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE);
137 mdelay(10);
138
139 ath79_device_reset_clear(AR724X_RESET_USB_HOST);
140 mdelay(10);
141
142 ath79_device_reset_clear(AR724X_RESET_USB_PHY);
143 mdelay(10);
144
145 ath79_usb_register("ehci-platform", -1,
146 AR724X_EHCI_BASE, AR724X_EHCI_SIZE,
147 ATH79_CPU_IRQ(3),
148 &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
149}
150
151static void __init ar913x_usb_setup(void)
152{
153 ath79_device_reset_set(AR913X_RESET_USBSUS_OVERRIDE);
154 mdelay(10);
155
156 ath79_device_reset_clear(AR913X_RESET_USB_HOST);
157 mdelay(10);
158
159 ath79_device_reset_clear(AR913X_RESET_USB_PHY);
160 mdelay(10);
161
162 ath79_usb_register("ehci-platform", -1,
163 AR913X_EHCI_BASE, AR913X_EHCI_SIZE,
164 ATH79_CPU_IRQ(3),
165 &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
166}
167
168static void __init ar933x_usb_setup(void)
169{
170 ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE);
171 mdelay(10);
172
173 ath79_device_reset_clear(AR933X_RESET_USB_HOST);
174 mdelay(10);
175
176 ath79_device_reset_clear(AR933X_RESET_USB_PHY);
177 mdelay(10);
178
179 ath79_usb_register("ehci-platform", -1,
180 AR933X_EHCI_BASE, AR933X_EHCI_SIZE,
181 ATH79_CPU_IRQ(3),
182 &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
183}
184
185static void __init ar934x_usb_setup(void)
186{
187 u32 bootstrap;
188
189 bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
190 if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
191 return;
192
193 ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE);
194 udelay(1000);
195
196 ath79_device_reset_clear(AR934X_RESET_USB_PHY);
197 udelay(1000);
198
199 ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG);
200 udelay(1000);
201
202 ath79_device_reset_clear(AR934X_RESET_USB_HOST);
203 udelay(1000);
204
205 ath79_usb_register("ehci-platform", -1,
206 AR934X_EHCI_BASE, AR934X_EHCI_SIZE,
207 ATH79_CPU_IRQ(3),
208 &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
209}
210
211static void __init qca955x_usb_setup(void)
212{
213 ath79_usb_register("ehci-platform", 0,
214 QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE,
215 ATH79_IP3_IRQ(0),
216 &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
217
218 ath79_usb_register("ehci-platform", 1,
219 QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE,
220 ATH79_IP3_IRQ(1),
221 &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
222}
223
224void __init ath79_register_usb(void)
225{
226 if (soc_is_ar71xx())
227 ath79_usb_setup();
228 else if (soc_is_ar7240())
229 ar7240_usb_setup();
230 else if (soc_is_ar7241() || soc_is_ar7242())
231 ar724x_usb_setup();
232 else if (soc_is_ar913x())
233 ar913x_usb_setup();
234 else if (soc_is_ar933x())
235 ar933x_usb_setup();
236 else if (soc_is_ar934x())
237 ar934x_usb_setup();
238 else if (soc_is_qca955x())
239 qca955x_usb_setup();
240 else
241 BUG();
242}
diff --git a/arch/mips/ath79/dev-usb.h b/arch/mips/ath79/dev-usb.h
deleted file mode 100644
index 4b86a69ca080..000000000000
--- a/arch/mips/ath79/dev-usb.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X USB Host Controller support
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#ifndef _ATH79_DEV_USB_H
13#define _ATH79_DEV_USB_H
14
15void ath79_register_usb(void);
16
17#endif /* _ATH79_DEV_USB_H */
diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c
deleted file mode 100644
index da190b1b87ce..000000000000
--- a/arch/mips/ath79/dev-wmac.c
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 * Atheros AR913X/AR933X SoC built-in WMAC device support
3 *
4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/irq.h>
18#include <linux/platform_device.h>
19#include <linux/ath9k_platform.h>
20
21#include <asm/mach-ath79/ath79.h>
22#include <asm/mach-ath79/ar71xx_regs.h>
23#include "dev-wmac.h"
24
25static struct ath9k_platform_data ath79_wmac_data;
26
27static struct resource ath79_wmac_resources[] = {
28 {
29 /* .start and .end fields are filled dynamically */
30 .flags = IORESOURCE_MEM,
31 }, {
32 /* .start and .end fields are filled dynamically */
33 .flags = IORESOURCE_IRQ,
34 },
35};
36
37static struct platform_device ath79_wmac_device = {
38 .name = "ath9k",
39 .id = -1,
40 .resource = ath79_wmac_resources,
41 .num_resources = ARRAY_SIZE(ath79_wmac_resources),
42 .dev = {
43 .platform_data = &ath79_wmac_data,
44 },
45};
46
47static void __init ar913x_wmac_setup(void)
48{
49 /* reset the WMAC */
50 ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
51 mdelay(10);
52
53 ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
54 mdelay(10);
55
56 ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
57 ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
58 ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2);
59 ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2);
60}
61
62
63static int ar933x_wmac_reset(void)
64{
65 ath79_device_reset_set(AR933X_RESET_WMAC);
66 ath79_device_reset_clear(AR933X_RESET_WMAC);
67
68 return 0;
69}
70
71static int ar933x_r1_get_wmac_revision(void)
72{
73 return ath79_soc_rev;
74}
75
76static void __init ar933x_wmac_setup(void)
77{
78 u32 t;
79
80 ar933x_wmac_reset();
81
82 ath79_wmac_device.name = "ar933x_wmac";
83
84 ath79_wmac_resources[0].start = AR933X_WMAC_BASE;
85 ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
86 ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2);
87 ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2);
88
89 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
90 if (t & AR933X_BOOTSTRAP_REF_CLK_40)
91 ath79_wmac_data.is_clk_25mhz = false;
92 else
93 ath79_wmac_data.is_clk_25mhz = true;
94
95 if (ath79_soc_rev == 1)
96 ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision;
97
98 ath79_wmac_data.external_reset = ar933x_wmac_reset;
99}
100
101static void ar934x_wmac_setup(void)
102{
103 u32 t;
104
105 ath79_wmac_device.name = "ar934x_wmac";
106
107 ath79_wmac_resources[0].start = AR934X_WMAC_BASE;
108 ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1;
109 ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
110 ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1);
111
112 t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
113 if (t & AR934X_BOOTSTRAP_REF_CLK_40)
114 ath79_wmac_data.is_clk_25mhz = false;
115 else
116 ath79_wmac_data.is_clk_25mhz = true;
117}
118
119static void qca955x_wmac_setup(void)
120{
121 u32 t;
122
123 ath79_wmac_device.name = "qca955x_wmac";
124
125 ath79_wmac_resources[0].start = QCA955X_WMAC_BASE;
126 ath79_wmac_resources[0].end = QCA955X_WMAC_BASE + QCA955X_WMAC_SIZE - 1;
127 ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
128 ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1);
129
130 t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
131 if (t & QCA955X_BOOTSTRAP_REF_CLK_40)
132 ath79_wmac_data.is_clk_25mhz = false;
133 else
134 ath79_wmac_data.is_clk_25mhz = true;
135}
136
137void __init ath79_register_wmac(u8 *cal_data)
138{
139 if (soc_is_ar913x())
140 ar913x_wmac_setup();
141 else if (soc_is_ar933x())
142 ar933x_wmac_setup();
143 else if (soc_is_ar934x())
144 ar934x_wmac_setup();
145 else if (soc_is_qca955x())
146 qca955x_wmac_setup();
147 else
148 BUG();
149
150 if (cal_data)
151 memcpy(ath79_wmac_data.eeprom_data, cal_data,
152 sizeof(ath79_wmac_data.eeprom_data));
153
154 platform_device_register(&ath79_wmac_device);
155}
diff --git a/arch/mips/ath79/dev-wmac.h b/arch/mips/ath79/dev-wmac.h
deleted file mode 100644
index c9cd8709f090..000000000000
--- a/arch/mips/ath79/dev-wmac.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * Atheros AR913X/AR933X SoC built-in WMAC device support
3 *
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#ifndef _ATH79_DEV_WMAC_H
13#define _ATH79_DEV_WMAC_H
14
15void ath79_register_wmac(u8 *cal_data);
16
17#endif /* _ATH79_DEV_WMAC_H */
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
deleted file mode 100644
index 2dfff1f19004..000000000000
--- a/arch/mips/ath79/irq.c
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2 * Atheros AR71xx/AR724x/AR913x specific interrupt handling
3 *
4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <linux/irqchip.h>
19#include <linux/of_irq.h>
20
21#include <asm/irq_cpu.h>
22#include <asm/mipsregs.h>
23
24#include <asm/mach-ath79/ath79.h>
25#include <asm/mach-ath79/ar71xx_regs.h>
26#include "common.h"
27#include "machtypes.h"
28
29
30static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
31{
32 u32 status;
33
34 status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
35
36 if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {
37 ath79_ddr_wb_flush(3);
38 generic_handle_irq(ATH79_IP2_IRQ(0));
39 } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) {
40 ath79_ddr_wb_flush(4);
41 generic_handle_irq(ATH79_IP2_IRQ(1));
42 } else {
43 spurious_interrupt();
44 }
45}
46
47static void ar934x_ip2_irq_init(void)
48{
49 int i;
50
51 for (i = ATH79_IP2_IRQ_BASE;
52 i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
53 irq_set_chip_and_handler(i, &dummy_irq_chip,
54 handle_level_irq);
55
56 irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch);
57}
58
59static void qca955x_ip2_irq_dispatch(struct irq_desc *desc)
60{
61 u32 status;
62
63 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
64 status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL;
65
66 if (status == 0) {
67 spurious_interrupt();
68 return;
69 }
70
71 if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) {
72 /* TODO: flush DDR? */
73 generic_handle_irq(ATH79_IP2_IRQ(0));
74 }
75
76 if (status & QCA955X_EXT_INT_WMAC_ALL) {
77 /* TODO: flush DDR? */
78 generic_handle_irq(ATH79_IP2_IRQ(1));
79 }
80}
81
82static void qca955x_ip3_irq_dispatch(struct irq_desc *desc)
83{
84 u32 status;
85
86 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
87 status &= QCA955X_EXT_INT_PCIE_RC2_ALL |
88 QCA955X_EXT_INT_USB1 |
89 QCA955X_EXT_INT_USB2;
90
91 if (status == 0) {
92 spurious_interrupt();
93 return;
94 }
95
96 if (status & QCA955X_EXT_INT_USB1) {
97 /* TODO: flush DDR? */
98 generic_handle_irq(ATH79_IP3_IRQ(0));
99 }
100
101 if (status & QCA955X_EXT_INT_USB2) {
102 /* TODO: flush DDR? */
103 generic_handle_irq(ATH79_IP3_IRQ(1));
104 }
105
106 if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) {
107 /* TODO: flush DDR? */
108 generic_handle_irq(ATH79_IP3_IRQ(2));
109 }
110}
111
112static void qca955x_irq_init(void)
113{
114 int i;
115
116 for (i = ATH79_IP2_IRQ_BASE;
117 i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
118 irq_set_chip_and_handler(i, &dummy_irq_chip,
119 handle_level_irq);
120
121 irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch);
122
123 for (i = ATH79_IP3_IRQ_BASE;
124 i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
125 irq_set_chip_and_handler(i, &dummy_irq_chip,
126 handle_level_irq);
127
128 irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
129}
130
131void __init arch_init_irq(void)
132{
133 unsigned irq_wb_chan2 = -1;
134 unsigned irq_wb_chan3 = -1;
135 bool misc_is_ar71xx;
136
137 if (mips_machtype == ATH79_MACH_GENERIC_OF) {
138 irqchip_init();
139 return;
140 }
141
142 if (soc_is_ar71xx() || soc_is_ar724x() ||
143 soc_is_ar913x() || soc_is_ar933x()) {
144 irq_wb_chan2 = 3;
145 irq_wb_chan3 = 2;
146 } else if (soc_is_ar934x()) {
147 irq_wb_chan3 = 2;
148 }
149
150 ath79_cpu_irq_init(irq_wb_chan2, irq_wb_chan3);
151
152 if (soc_is_ar71xx() || soc_is_ar913x())
153 misc_is_ar71xx = true;
154 else if (soc_is_ar724x() ||
155 soc_is_ar933x() ||
156 soc_is_ar934x() ||
157 soc_is_qca955x())
158 misc_is_ar71xx = false;
159 else
160 BUG();
161 ath79_misc_irq_init(
162 ath79_reset_base + AR71XX_RESET_REG_MISC_INT_STATUS,
163 ATH79_CPU_IRQ(6), ATH79_MISC_IRQ_BASE, misc_is_ar71xx);
164
165 if (soc_is_ar934x())
166 ar934x_ip2_irq_init();
167 else if (soc_is_qca955x())
168 qca955x_irq_init();
169}
diff --git a/arch/mips/ath79/mach-ap121.c b/arch/mips/ath79/mach-ap121.c
deleted file mode 100644
index 1bf73f2a069d..000000000000
--- a/arch/mips/ath79/mach-ap121.c
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2 * Atheros AP121 board support
3 *
4 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
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 version 2 as published
8 * by the Free Software Foundation.
9 */
10
11#include "machtypes.h"
12#include "dev-gpio-buttons.h"
13#include "dev-leds-gpio.h"
14#include "dev-spi.h"
15#include "dev-usb.h"
16#include "dev-wmac.h"
17
18#define AP121_GPIO_LED_WLAN 0
19#define AP121_GPIO_LED_USB 1
20
21#define AP121_GPIO_BTN_JUMPSTART 11
22#define AP121_GPIO_BTN_RESET 12
23
24#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */
25#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL)
26
27#define AP121_CAL_DATA_ADDR 0x1fff1000
28
29static struct gpio_led ap121_leds_gpio[] __initdata = {
30 {
31 .name = "ap121:green:usb",
32 .gpio = AP121_GPIO_LED_USB,
33 .active_low = 0,
34 },
35 {
36 .name = "ap121:green:wlan",
37 .gpio = AP121_GPIO_LED_WLAN,
38 .active_low = 0,
39 },
40};
41
42static struct gpio_keys_button ap121_gpio_keys[] __initdata = {
43 {
44 .desc = "jumpstart button",
45 .type = EV_KEY,
46 .code = KEY_WPS_BUTTON,
47 .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
48 .gpio = AP121_GPIO_BTN_JUMPSTART,
49 .active_low = 1,
50 },
51 {
52 .desc = "reset button",
53 .type = EV_KEY,
54 .code = KEY_RESTART,
55 .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
56 .gpio = AP121_GPIO_BTN_RESET,
57 .active_low = 1,
58 }
59};
60
61static struct spi_board_info ap121_spi_info[] = {
62 {
63 .bus_num = 0,
64 .chip_select = 0,
65 .max_speed_hz = 25000000,
66 .modalias = "mx25l1606e",
67 }
68};
69
70static struct ath79_spi_platform_data ap121_spi_data = {
71 .bus_num = 0,
72 .num_chipselect = 1,
73};
74
75static void __init ap121_setup(void)
76{
77 u8 *cal_data = (u8 *) KSEG1ADDR(AP121_CAL_DATA_ADDR);
78
79 ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio),
80 ap121_leds_gpio);
81 ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL,
82 ARRAY_SIZE(ap121_gpio_keys),
83 ap121_gpio_keys);
84
85 ath79_register_spi(&ap121_spi_data, ap121_spi_info,
86 ARRAY_SIZE(ap121_spi_info));
87 ath79_register_usb();
88 ath79_register_wmac(cal_data);
89}
90
91MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board",
92 ap121_setup);
diff --git a/arch/mips/ath79/mach-ap136.c b/arch/mips/ath79/mach-ap136.c
deleted file mode 100644
index 07eac58c3641..000000000000
--- a/arch/mips/ath79/mach-ap136.c
+++ /dev/null
@@ -1,156 +0,0 @@
1/*
2 * Qualcomm Atheros AP136 reference board support
3 *
4 * Copyright (c) 2012 Qualcomm Atheros
5 * Copyright (c) 2012-2013 Gabor Juhos <juhosg@openwrt.org>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21#include <linux/pci.h>
22#include <linux/ath9k_platform.h>
23
24#include "machtypes.h"
25#include "dev-gpio-buttons.h"
26#include "dev-leds-gpio.h"
27#include "dev-spi.h"
28#include "dev-usb.h"
29#include "dev-wmac.h"
30#include "pci.h"
31
32#define AP136_GPIO_LED_STATUS_RED 14
33#define AP136_GPIO_LED_STATUS_GREEN 19
34#define AP136_GPIO_LED_USB 4
35#define AP136_GPIO_LED_WLAN_2G 13
36#define AP136_GPIO_LED_WLAN_5G 12
37#define AP136_GPIO_LED_WPS_RED 15
38#define AP136_GPIO_LED_WPS_GREEN 20
39
40#define AP136_GPIO_BTN_WPS 16
41#define AP136_GPIO_BTN_RFKILL 21
42
43#define AP136_KEYS_POLL_INTERVAL 20 /* msecs */
44#define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL)
45
46#define AP136_WMAC_CALDATA_OFFSET 0x1000
47#define AP136_PCIE_CALDATA_OFFSET 0x5000
48
49static struct gpio_led ap136_leds_gpio[] __initdata = {
50 {
51 .name = "qca:green:status",
52 .gpio = AP136_GPIO_LED_STATUS_GREEN,
53 .active_low = 1,
54 },
55 {
56 .name = "qca:red:status",
57 .gpio = AP136_GPIO_LED_STATUS_RED,
58 .active_low = 1,
59 },
60 {
61 .name = "qca:green:wps",
62 .gpio = AP136_GPIO_LED_WPS_GREEN,
63 .active_low = 1,
64 },
65 {
66 .name = "qca:red:wps",
67 .gpio = AP136_GPIO_LED_WPS_RED,
68 .active_low = 1,
69 },
70 {
71 .name = "qca:red:wlan-2g",
72 .gpio = AP136_GPIO_LED_WLAN_2G,
73 .active_low = 1,
74 },
75 {
76 .name = "qca:red:usb",
77 .gpio = AP136_GPIO_LED_USB,
78 .active_low = 1,
79 }
80};
81
82static struct gpio_keys_button ap136_gpio_keys[] __initdata = {
83 {
84 .desc = "WPS button",
85 .type = EV_KEY,
86 .code = KEY_WPS_BUTTON,
87 .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL,
88 .gpio = AP136_GPIO_BTN_WPS,
89 .active_low = 1,
90 },
91 {
92 .desc = "RFKILL button",
93 .type = EV_KEY,
94 .code = KEY_RFKILL,
95 .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL,
96 .gpio = AP136_GPIO_BTN_RFKILL,
97 .active_low = 1,
98 },
99};
100
101static struct spi_board_info ap136_spi_info[] = {
102 {
103 .bus_num = 0,
104 .chip_select = 0,
105 .max_speed_hz = 25000000,
106 .modalias = "mx25l6405d",
107 }
108};
109
110static struct ath79_spi_platform_data ap136_spi_data = {
111 .bus_num = 0,
112 .num_chipselect = 1,
113};
114
115#ifdef CONFIG_PCI
116static struct ath9k_platform_data ap136_ath9k_data;
117
118static int ap136_pci_plat_dev_init(struct pci_dev *dev)
119{
120 if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0)
121 dev->dev.platform_data = &ap136_ath9k_data;
122
123 return 0;
124}
125
126static void __init ap136_pci_init(u8 *eeprom)
127{
128 memcpy(ap136_ath9k_data.eeprom_data, eeprom,
129 sizeof(ap136_ath9k_data.eeprom_data));
130
131 ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init);
132 ath79_register_pci();
133}
134#else
135static inline void ap136_pci_init(u8 *eeprom) {}
136#endif /* CONFIG_PCI */
137
138static void __init ap136_setup(void)
139{
140 u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
141
142 ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio),
143 ap136_leds_gpio);
144 ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL,
145 ARRAY_SIZE(ap136_gpio_keys),
146 ap136_gpio_keys);
147 ath79_register_spi(&ap136_spi_data, ap136_spi_info,
148 ARRAY_SIZE(ap136_spi_info));
149 ath79_register_usb();
150 ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET);
151 ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET);
152}
153
154MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010",
155 "Atheros AP136-010 reference board",
156 ap136_setup);
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
deleted file mode 100644
index 1c78d497f930..000000000000
--- a/arch/mips/ath79/mach-ap81.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * Atheros AP81 board support
3 *
4 * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#include "machtypes.h"
13#include "dev-wmac.h"
14#include "dev-gpio-buttons.h"
15#include "dev-leds-gpio.h"
16#include "dev-spi.h"
17#include "dev-usb.h"
18
19#define AP81_GPIO_LED_STATUS 1
20#define AP81_GPIO_LED_AOSS 3
21#define AP81_GPIO_LED_WLAN 6
22#define AP81_GPIO_LED_POWER 14
23
24#define AP81_GPIO_BTN_SW4 12
25#define AP81_GPIO_BTN_SW1 21
26
27#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */
28#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL)
29
30#define AP81_CAL_DATA_ADDR 0x1fff1000
31
32static struct gpio_led ap81_leds_gpio[] __initdata = {
33 {
34 .name = "ap81:green:status",
35 .gpio = AP81_GPIO_LED_STATUS,
36 .active_low = 1,
37 }, {
38 .name = "ap81:amber:aoss",
39 .gpio = AP81_GPIO_LED_AOSS,
40 .active_low = 1,
41 }, {
42 .name = "ap81:green:wlan",
43 .gpio = AP81_GPIO_LED_WLAN,
44 .active_low = 1,
45 }, {
46 .name = "ap81:green:power",
47 .gpio = AP81_GPIO_LED_POWER,
48 .active_low = 1,
49 }
50};
51
52static struct gpio_keys_button ap81_gpio_keys[] __initdata = {
53 {
54 .desc = "sw1",
55 .type = EV_KEY,
56 .code = BTN_0,
57 .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
58 .gpio = AP81_GPIO_BTN_SW1,
59 .active_low = 1,
60 } , {
61 .desc = "sw4",
62 .type = EV_KEY,
63 .code = BTN_1,
64 .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
65 .gpio = AP81_GPIO_BTN_SW4,
66 .active_low = 1,
67 }
68};
69
70static struct spi_board_info ap81_spi_info[] = {
71 {
72 .bus_num = 0,
73 .chip_select = 0,
74 .max_speed_hz = 25000000,
75 .modalias = "m25p64",
76 }
77};
78
79static struct ath79_spi_platform_data ap81_spi_data = {
80 .bus_num = 0,
81 .num_chipselect = 1,
82};
83
84static void __init ap81_setup(void)
85{
86 u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR);
87
88 ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
89 ap81_leds_gpio);
90 ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
91 ARRAY_SIZE(ap81_gpio_keys),
92 ap81_gpio_keys);
93 ath79_register_spi(&ap81_spi_data, ap81_spi_info,
94 ARRAY_SIZE(ap81_spi_info));
95 ath79_register_wmac(cal_data);
96 ath79_register_usb();
97}
98
99MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
100 ap81_setup);
diff --git a/arch/mips/ath79/mach-db120.c b/arch/mips/ath79/mach-db120.c
deleted file mode 100644
index 9423f5aed287..000000000000
--- a/arch/mips/ath79/mach-db120.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/*
2 * Atheros DB120 reference board support
3 *
4 * Copyright (c) 2011 Qualcomm Atheros
5 * Copyright (c) 2011 Gabor Juhos <juhosg@openwrt.org>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21#include <linux/pci.h>
22#include <linux/ath9k_platform.h>
23
24#include "machtypes.h"
25#include "dev-gpio-buttons.h"
26#include "dev-leds-gpio.h"
27#include "dev-spi.h"
28#include "dev-usb.h"
29#include "dev-wmac.h"
30#include "pci.h"
31
32#define DB120_GPIO_LED_WLAN_5G 12
33#define DB120_GPIO_LED_WLAN_2G 13
34#define DB120_GPIO_LED_STATUS 14
35#define DB120_GPIO_LED_WPS 15
36
37#define DB120_GPIO_BTN_WPS 16
38
39#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */
40#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL)
41
42#define DB120_WMAC_CALDATA_OFFSET 0x1000
43#define DB120_PCIE_CALDATA_OFFSET 0x5000
44
45static struct gpio_led db120_leds_gpio[] __initdata = {
46 {
47 .name = "db120:green:status",
48 .gpio = DB120_GPIO_LED_STATUS,
49 .active_low = 1,
50 },
51 {
52 .name = "db120:green:wps",
53 .gpio = DB120_GPIO_LED_WPS,
54 .active_low = 1,
55 },
56 {
57 .name = "db120:green:wlan-5g",
58 .gpio = DB120_GPIO_LED_WLAN_5G,
59 .active_low = 1,
60 },
61 {
62 .name = "db120:green:wlan-2g",
63 .gpio = DB120_GPIO_LED_WLAN_2G,
64 .active_low = 1,
65 },
66};
67
68static struct gpio_keys_button db120_gpio_keys[] __initdata = {
69 {
70 .desc = "WPS button",
71 .type = EV_KEY,
72 .code = KEY_WPS_BUTTON,
73 .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL,
74 .gpio = DB120_GPIO_BTN_WPS,
75 .active_low = 1,
76 },
77};
78
79static struct spi_board_info db120_spi_info[] = {
80 {
81 .bus_num = 0,
82 .chip_select = 0,
83 .max_speed_hz = 25000000,
84 .modalias = "s25sl064a",
85 }
86};
87
88static struct ath79_spi_platform_data db120_spi_data = {
89 .bus_num = 0,
90 .num_chipselect = 1,
91};
92
93#ifdef CONFIG_PCI
94static struct ath9k_platform_data db120_ath9k_data;
95
96static int db120_pci_plat_dev_init(struct pci_dev *dev)
97{
98 switch (PCI_SLOT(dev->devfn)) {
99 case 0:
100 dev->dev.platform_data = &db120_ath9k_data;
101 break;
102 }
103
104 return 0;
105}
106
107static void __init db120_pci_init(u8 *eeprom)
108{
109 memcpy(db120_ath9k_data.eeprom_data, eeprom,
110 sizeof(db120_ath9k_data.eeprom_data));
111
112 ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init);
113 ath79_register_pci();
114}
115#else
116static inline void db120_pci_init(u8 *eeprom) {}
117#endif /* CONFIG_PCI */
118
119static void __init db120_setup(void)
120{
121 u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
122
123 ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio),
124 db120_leds_gpio);
125 ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL,
126 ARRAY_SIZE(db120_gpio_keys),
127 db120_gpio_keys);
128 ath79_register_spi(&db120_spi_data, db120_spi_info,
129 ARRAY_SIZE(db120_spi_info));
130 ath79_register_usb();
131 ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET);
132 db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
133}
134
135MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board",
136 db120_setup);
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
deleted file mode 100644
index 75fb96ca61db..000000000000
--- a/arch/mips/ath79/mach-pb44.c
+++ /dev/null
@@ -1,128 +0,0 @@
1/*
2 * Atheros PB44 reference board support
3 *
4 * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
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 version 2 as published
8 * by the Free Software Foundation.
9 */
10
11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <linux/i2c.h>
14#include <linux/gpio/machine.h>
15#include <linux/platform_data/pcf857x.h>
16
17#include "machtypes.h"
18#include "dev-gpio-buttons.h"
19#include "dev-leds-gpio.h"
20#include "dev-spi.h"
21#include "dev-usb.h"
22#include "pci.h"
23
24#define PB44_GPIO_I2C_SCL 0
25#define PB44_GPIO_I2C_SDA 1
26
27#define PB44_GPIO_EXP_BASE 16
28#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6)
29#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8)
30#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9)
31#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + 10)
32
33#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */
34#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL)
35
36static struct gpiod_lookup_table pb44_i2c_gpiod_table = {
37 .dev_id = "i2c-gpio.0",
38 .table = {
39 GPIO_LOOKUP_IDX("ath79-gpio", PB44_GPIO_I2C_SDA,
40 NULL, 0, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
41 GPIO_LOOKUP_IDX("ath79-gpio", PB44_GPIO_I2C_SCL,
42 NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
43 },
44};
45
46static struct platform_device pb44_i2c_gpio_device = {
47 .name = "i2c-gpio",
48 .id = 0,
49 .dev = {
50 .platform_data = NULL,
51 }
52};
53
54static struct pcf857x_platform_data pb44_pcf857x_data = {
55 .gpio_base = PB44_GPIO_EXP_BASE,
56};
57
58static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
59 {
60 I2C_BOARD_INFO("pcf8575", 0x20),
61 .platform_data = &pb44_pcf857x_data,
62 },
63};
64
65static struct gpio_led pb44_leds_gpio[] __initdata = {
66 {
67 .name = "pb44:amber:jump1",
68 .gpio = PB44_GPIO_LED_JUMP1,
69 .active_low = 1,
70 }, {
71 .name = "pb44:green:jump2",
72 .gpio = PB44_GPIO_LED_JUMP2,
73 .active_low = 1,
74 },
75};
76
77static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
78 {
79 .desc = "soft_reset",
80 .type = EV_KEY,
81 .code = KEY_RESTART,
82 .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
83 .gpio = PB44_GPIO_SW_RESET,
84 .active_low = 1,
85 } , {
86 .desc = "jumpstart",
87 .type = EV_KEY,
88 .code = KEY_WPS_BUTTON,
89 .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
90 .gpio = PB44_GPIO_SW_JUMP,
91 .active_low = 1,
92 }
93};
94
95static struct spi_board_info pb44_spi_info[] = {
96 {
97 .bus_num = 0,
98 .chip_select = 0,
99 .max_speed_hz = 25000000,
100 .modalias = "m25p64",
101 },
102};
103
104static struct ath79_spi_platform_data pb44_spi_data = {
105 .bus_num = 0,
106 .num_chipselect = 1,
107};
108
109static void __init pb44_init(void)
110{
111 gpiod_add_lookup_table(&pb44_i2c_gpiod_table);
112 i2c_register_board_info(0, pb44_i2c_board_info,
113 ARRAY_SIZE(pb44_i2c_board_info));
114 platform_device_register(&pb44_i2c_gpio_device);
115
116 ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
117 pb44_leds_gpio);
118 ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
119 ARRAY_SIZE(pb44_gpio_keys),
120 pb44_gpio_keys);
121 ath79_register_spi(&pb44_spi_data, pb44_spi_info,
122 ARRAY_SIZE(pb44_spi_info));
123 ath79_register_usb();
124 ath79_register_pci();
125}
126
127MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
128 pb44_init);
diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
deleted file mode 100644
index 4a3c60694c75..000000000000
--- a/arch/mips/ath79/mach-ubnt-xm.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/*
2 * Ubiquiti Networks XM (rev 1.0) board support
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 *
6 * Derived from: mach-pb44.c
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/pci.h>
15#include <linux/ath9k_platform.h>
16
17#include <asm/mach-ath79/irq.h>
18
19#include "machtypes.h"
20#include "dev-gpio-buttons.h"
21#include "dev-leds-gpio.h"
22#include "dev-spi.h"
23#include "pci.h"
24
25#define UBNT_XM_GPIO_LED_L1 0
26#define UBNT_XM_GPIO_LED_L2 1
27#define UBNT_XM_GPIO_LED_L3 11
28#define UBNT_XM_GPIO_LED_L4 7
29
30#define UBNT_XM_GPIO_BTN_RESET 12
31
32#define UBNT_XM_KEYS_POLL_INTERVAL 20
33#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL)
34
35#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000)
36
37static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
38 {
39 .name = "ubnt-xm:red:link1",
40 .gpio = UBNT_XM_GPIO_LED_L1,
41 .active_low = 0,
42 }, {
43 .name = "ubnt-xm:orange:link2",
44 .gpio = UBNT_XM_GPIO_LED_L2,
45 .active_low = 0,
46 }, {
47 .name = "ubnt-xm:green:link3",
48 .gpio = UBNT_XM_GPIO_LED_L3,
49 .active_low = 0,
50 }, {
51 .name = "ubnt-xm:green:link4",
52 .gpio = UBNT_XM_GPIO_LED_L4,
53 .active_low = 0,
54 },
55};
56
57static struct gpio_keys_button ubnt_xm_gpio_keys[] __initdata = {
58 {
59 .desc = "reset",
60 .type = EV_KEY,
61 .code = KEY_RESTART,
62 .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL,
63 .gpio = UBNT_XM_GPIO_BTN_RESET,
64 .active_low = 1,
65 }
66};
67
68static struct spi_board_info ubnt_xm_spi_info[] = {
69 {
70 .bus_num = 0,
71 .chip_select = 0,
72 .max_speed_hz = 25000000,
73 .modalias = "mx25l6405d",
74 }
75};
76
77static struct ath79_spi_platform_data ubnt_xm_spi_data = {
78 .bus_num = 0,
79 .num_chipselect = 1,
80};
81
82#ifdef CONFIG_PCI
83static struct ath9k_platform_data ubnt_xm_eeprom_data;
84
85static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
86{
87 switch (PCI_SLOT(dev->devfn)) {
88 case 0:
89 dev->dev.platform_data = &ubnt_xm_eeprom_data;
90 break;
91 }
92
93 return 0;
94}
95
96static void __init ubnt_xm_pci_init(void)
97{
98 memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
99 sizeof(ubnt_xm_eeprom_data.eeprom_data));
100
101 ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
102 ath79_register_pci();
103}
104#else
105static inline void ubnt_xm_pci_init(void) {}
106#endif /* CONFIG_PCI */
107
108static void __init ubnt_xm_init(void)
109{
110 ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio),
111 ubnt_xm_leds_gpio);
112
113 ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
114 ARRAY_SIZE(ubnt_xm_gpio_keys),
115 ubnt_xm_gpio_keys);
116
117 ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info,
118 ARRAY_SIZE(ubnt_xm_spi_info));
119
120 ubnt_xm_pci_init();
121}
122
123MIPS_MACHINE(ATH79_MACH_UBNT_XM,
124 "UBNT-XM",
125 "Ubiquiti Networks XM (rev 1.0) board",
126 ubnt_xm_init);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
deleted file mode 100644
index a13db3d15c8f..000000000000
--- a/arch/mips/ath79/machtypes.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X/AR913X machine type definitions
3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
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
9 * by the Free Software Foundation.
10 */
11
12#ifndef _ATH79_MACHTYPE_H
13#define _ATH79_MACHTYPE_H
14
15#include <asm/mips_machine.h>
16
17enum ath79_mach_type {
18 ATH79_MACH_GENERIC_OF = -1, /* Device tree board */
19 ATH79_MACH_GENERIC = 0,
20 ATH79_MACH_AP121, /* Atheros AP121 reference board */
21 ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */
22 ATH79_MACH_AP81, /* Atheros AP81 reference board */
23 ATH79_MACH_DB120, /* Atheros DB120 reference board */
24 ATH79_MACH_PB44, /* Atheros PB44 reference board */
25 ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */
26};
27
28#endif /* _ATH79_MACHTYPE_H */
diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
deleted file mode 100644
index b816cb4a25ff..000000000000
--- a/arch/mips/ath79/pci.c
+++ /dev/null
@@ -1,273 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X specific PCI setup code
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * Parts of this file are based on Atheros' 2.6.15 BSP
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/pci.h>
17#include <linux/resource.h>
18#include <linux/platform_device.h>
19#include <asm/mach-ath79/ar71xx_regs.h>
20#include <asm/mach-ath79/ath79.h>
21#include <asm/mach-ath79/irq.h>
22#include "pci.h"
23
24static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
25static const struct ath79_pci_irq *ath79_pci_irq_map;
26static unsigned ath79_pci_nr_irqs;
27
28static const struct ath79_pci_irq ar71xx_pci_irq_map[] = {
29 {
30 .slot = 17,
31 .pin = 1,
32 .irq = ATH79_PCI_IRQ(0),
33 }, {
34 .slot = 18,
35 .pin = 1,
36 .irq = ATH79_PCI_IRQ(1),
37 }, {
38 .slot = 19,
39 .pin = 1,
40 .irq = ATH79_PCI_IRQ(2),
41 }
42};
43
44static const struct ath79_pci_irq ar724x_pci_irq_map[] = {
45 {
46 .slot = 0,
47 .pin = 1,
48 .irq = ATH79_PCI_IRQ(0),
49 }
50};
51
52static const struct ath79_pci_irq qca955x_pci_irq_map[] = {
53 {
54 .bus = 0,
55 .slot = 0,
56 .pin = 1,
57 .irq = ATH79_PCI_IRQ(0),
58 },
59 {
60 .bus = 1,
61 .slot = 0,
62 .pin = 1,
63 .irq = ATH79_PCI_IRQ(1),
64 },
65};
66
67int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
68{
69 int irq = -1;
70 int i;
71
72 if (ath79_pci_nr_irqs == 0 ||
73 ath79_pci_irq_map == NULL) {
74 if (soc_is_ar71xx()) {
75 ath79_pci_irq_map = ar71xx_pci_irq_map;
76 ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map);
77 } else if (soc_is_ar724x() ||
78 soc_is_ar9342() ||
79 soc_is_ar9344()) {
80 ath79_pci_irq_map = ar724x_pci_irq_map;
81 ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map);
82 } else if (soc_is_qca955x()) {
83 ath79_pci_irq_map = qca955x_pci_irq_map;
84 ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map);
85 } else {
86 pr_crit("pci %s: invalid irq map\n",
87 pci_name((struct pci_dev *) dev));
88 return irq;
89 }
90 }
91
92 for (i = 0; i < ath79_pci_nr_irqs; i++) {
93 const struct ath79_pci_irq *entry;
94
95 entry = &ath79_pci_irq_map[i];
96 if (entry->bus == dev->bus->number &&
97 entry->slot == slot &&
98 entry->pin == pin) {
99 irq = entry->irq;
100 break;
101 }
102 }
103
104 if (irq < 0)
105 pr_crit("pci %s: no irq found for pin %u\n",
106 pci_name((struct pci_dev *) dev), pin);
107 else
108 pr_info("pci %s: using irq %d for pin %u\n",
109 pci_name((struct pci_dev *) dev), irq, pin);
110
111 return irq;
112}
113
114int pcibios_plat_dev_init(struct pci_dev *dev)
115{
116 if (ath79_pci_plat_dev_init)
117 return ath79_pci_plat_dev_init(dev);
118
119 return 0;
120}
121
122void __init ath79_pci_set_irq_map(unsigned nr_irqs,
123 const struct ath79_pci_irq *map)
124{
125 ath79_pci_nr_irqs = nr_irqs;
126 ath79_pci_irq_map = map;
127}
128
129void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
130{
131 ath79_pci_plat_dev_init = func;
132}
133
134static struct platform_device *
135ath79_register_pci_ar71xx(void)
136{
137 struct platform_device *pdev;
138 struct resource res[4];
139
140 memset(res, 0, sizeof(res));
141
142 res[0].name = "cfg_base";
143 res[0].flags = IORESOURCE_MEM;
144 res[0].start = AR71XX_PCI_CFG_BASE;
145 res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1;
146
147 res[1].flags = IORESOURCE_IRQ;
148 res[1].start = ATH79_CPU_IRQ(2);
149 res[1].end = ATH79_CPU_IRQ(2);
150
151 res[2].name = "io_base";
152 res[2].flags = IORESOURCE_IO;
153 res[2].start = 0;
154 res[2].end = 0;
155
156 res[3].name = "mem_base";
157 res[3].flags = IORESOURCE_MEM;
158 res[3].start = AR71XX_PCI_MEM_BASE;
159 res[3].end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1;
160
161 pdev = platform_device_register_simple("ar71xx-pci", -1,
162 res, ARRAY_SIZE(res));
163 return pdev;
164}
165
166static struct platform_device *
167ath79_register_pci_ar724x(int id,
168 unsigned long cfg_base,
169 unsigned long ctrl_base,
170 unsigned long crp_base,
171 unsigned long mem_base,
172 unsigned long mem_size,
173 unsigned long io_base,
174 int irq)
175{
176 struct platform_device *pdev;
177 struct resource res[6];
178
179 memset(res, 0, sizeof(res));
180
181 res[0].name = "cfg_base";
182 res[0].flags = IORESOURCE_MEM;
183 res[0].start = cfg_base;
184 res[0].end = cfg_base + AR724X_PCI_CFG_SIZE - 1;
185
186 res[1].name = "ctrl_base";
187 res[1].flags = IORESOURCE_MEM;
188 res[1].start = ctrl_base;
189 res[1].end = ctrl_base + AR724X_PCI_CTRL_SIZE - 1;
190
191 res[2].flags = IORESOURCE_IRQ;
192 res[2].start = irq;
193 res[2].end = irq;
194
195 res[3].name = "mem_base";
196 res[3].flags = IORESOURCE_MEM;
197 res[3].start = mem_base;
198 res[3].end = mem_base + mem_size - 1;
199
200 res[4].name = "io_base";
201 res[4].flags = IORESOURCE_IO;
202 res[4].start = io_base;
203 res[4].end = io_base;
204
205 res[5].name = "crp_base";
206 res[5].flags = IORESOURCE_MEM;
207 res[5].start = crp_base;
208 res[5].end = crp_base + AR724X_PCI_CRP_SIZE - 1;
209
210 pdev = platform_device_register_simple("ar724x-pci", id,
211 res, ARRAY_SIZE(res));
212 return pdev;
213}
214
215int __init ath79_register_pci(void)
216{
217 struct platform_device *pdev = NULL;
218
219 if (soc_is_ar71xx()) {
220 pdev = ath79_register_pci_ar71xx();
221 } else if (soc_is_ar724x()) {
222 pdev = ath79_register_pci_ar724x(-1,
223 AR724X_PCI_CFG_BASE,
224 AR724X_PCI_CTRL_BASE,
225 AR724X_PCI_CRP_BASE,
226 AR724X_PCI_MEM_BASE,
227 AR724X_PCI_MEM_SIZE,
228 0,
229 ATH79_CPU_IRQ(2));
230 } else if (soc_is_ar9342() ||
231 soc_is_ar9344()) {
232 u32 bootstrap;
233
234 bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
235 if ((bootstrap & AR934X_BOOTSTRAP_PCIE_RC) == 0)
236 return -ENODEV;
237
238 pdev = ath79_register_pci_ar724x(-1,
239 AR724X_PCI_CFG_BASE,
240 AR724X_PCI_CTRL_BASE,
241 AR724X_PCI_CRP_BASE,
242 AR724X_PCI_MEM_BASE,
243 AR724X_PCI_MEM_SIZE,
244 0,
245 ATH79_IP2_IRQ(0));
246 } else if (soc_is_qca9558()) {
247 pdev = ath79_register_pci_ar724x(0,
248 QCA955X_PCI_CFG_BASE0,
249 QCA955X_PCI_CTRL_BASE0,
250 QCA955X_PCI_CRP_BASE0,
251 QCA955X_PCI_MEM_BASE0,
252 QCA955X_PCI_MEM_SIZE,
253 0,
254 ATH79_IP2_IRQ(0));
255
256 pdev = ath79_register_pci_ar724x(1,
257 QCA955X_PCI_CFG_BASE1,
258 QCA955X_PCI_CTRL_BASE1,
259 QCA955X_PCI_CRP_BASE1,
260 QCA955X_PCI_MEM_BASE1,
261 QCA955X_PCI_MEM_SIZE,
262 1,
263 ATH79_IP3_IRQ(2));
264 } else {
265 /* No PCI support */
266 return -ENODEV;
267 }
268
269 if (!pdev)
270 pr_err("unable to register PCI controller device\n");
271
272 return pdev ? 0 : -ENODEV;
273}
diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
deleted file mode 100644
index 1d00a3803c37..000000000000
--- a/arch/mips/ath79/pci.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * Atheros AR71XX/AR724X PCI support
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 */
12
13#ifndef _ATH79_PCI_H
14#define _ATH79_PCI_H
15
16struct ath79_pci_irq {
17 int bus;
18 u8 slot;
19 u8 pin;
20 int irq;
21};
22
23#ifdef CONFIG_PCI
24void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map);
25void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
26int ath79_register_pci(void);
27#else
28static inline void
29ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {}
30static inline void
31ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
32static inline int ath79_register_pci(void) { return 0; }
33#endif
34
35#endif /* _ATH79_PCI_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 9728abcb18fa..4a70c5de8c92 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -19,6 +19,7 @@
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/clk-provider.h> 20#include <linux/clk-provider.h>
21#include <linux/of_fdt.h> 21#include <linux/of_fdt.h>
22#include <linux/irqchip.h>
22 23
23#include <asm/bootinfo.h> 24#include <asm/bootinfo.h>
24#include <asm/idle.h> 25#include <asm/idle.h>
@@ -31,8 +32,6 @@
31#include <asm/mach-ath79/ath79.h> 32#include <asm/mach-ath79/ath79.h>
32#include <asm/mach-ath79/ar71xx_regs.h> 33#include <asm/mach-ath79/ar71xx_regs.h>
33#include "common.h" 34#include "common.h"
34#include "dev-common.h"
35#include "machtypes.h"
36 35
37#define ATH79_SYS_TYPE_LEN 64 36#define ATH79_SYS_TYPE_LEN 64
38 37
@@ -235,25 +234,21 @@ void __init plat_mem_setup(void)
235 else if (fw_passed_dtb) 234 else if (fw_passed_dtb)
236 __dt_setup_arch((void *)KSEG0ADDR(fw_passed_dtb)); 235 __dt_setup_arch((void *)KSEG0ADDR(fw_passed_dtb));
237 236
238 if (mips_machtype != ATH79_MACH_GENERIC_OF) { 237 ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
239 ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, 238 AR71XX_RESET_SIZE);
240 AR71XX_RESET_SIZE); 239 ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
241 ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, 240 AR71XX_PLL_SIZE);
242 AR71XX_PLL_SIZE); 241 ath79_detect_sys_type();
243 ath79_detect_sys_type(); 242 ath79_ddr_ctrl_init();
244 ath79_ddr_ctrl_init();
245 243
246 detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); 244 detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
247
248 /* OF machines should use the reset driver */
249 _machine_restart = ath79_restart;
250 }
251 245
246 _machine_restart = ath79_restart;
252 _machine_halt = ath79_halt; 247 _machine_halt = ath79_halt;
253 pm_power_off = ath79_halt; 248 pm_power_off = ath79_halt;
254} 249}
255 250
256static void __init ath79_of_plat_time_init(void) 251void __init plat_time_init(void)
257{ 252{
258 struct device_node *np; 253 struct device_node *np;
259 struct clk *clk; 254 struct clk *clk;
@@ -283,61 +278,12 @@ static void __init ath79_of_plat_time_init(void)
283 clk_put(clk); 278 clk_put(clk);
284} 279}
285 280
286void __init plat_time_init(void) 281void __init arch_init_irq(void)
287{
288 unsigned long cpu_clk_rate;
289 unsigned long ahb_clk_rate;
290 unsigned long ddr_clk_rate;
291 unsigned long ref_clk_rate;
292
293 if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) {
294 ath79_of_plat_time_init();
295 return;
296 }
297
298 ath79_clocks_init();
299
300 cpu_clk_rate = ath79_get_sys_clk_rate("cpu");
301 ahb_clk_rate = ath79_get_sys_clk_rate("ahb");
302 ddr_clk_rate = ath79_get_sys_clk_rate("ddr");
303 ref_clk_rate = ath79_get_sys_clk_rate("ref");
304
305 pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n",
306 cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000,
307 ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000,
308 ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000,
309 ref_clk_rate / 1000000, (ref_clk_rate / 1000) % 1000);
310
311 mips_hpt_frequency = cpu_clk_rate / 2;
312}
313
314static int __init ath79_setup(void)
315{ 282{
316 if (mips_machtype == ATH79_MACH_GENERIC_OF) 283 irqchip_init();
317 return 0;
318
319 ath79_gpio_init();
320 ath79_register_uart();
321 ath79_register_wdt();
322
323 mips_machine_setup();
324
325 return 0;
326} 284}
327 285
328arch_initcall(ath79_setup);
329
330void __init device_tree_init(void) 286void __init device_tree_init(void)
331{ 287{
332 unflatten_and_copy_device_tree(); 288 unflatten_and_copy_device_tree();
333} 289}
334
335MIPS_MACHINE(ATH79_MACH_GENERIC,
336 "Generic",
337 "Generic AR71XX/AR724X/AR913X based board",
338 NULL);
339
340MIPS_MACHINE(ATH79_MACH_GENERIC_OF,
341 "DTB",
342 "Generic AR71XX/AR724X/AR913X based board (DT)",
343 NULL);
diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c
index 977990a609ba..67b6a78d670b 100644
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -147,7 +147,7 @@ bcm47xx_buttons_buffalo_whr_g125[] __initconst = {
147static const struct gpio_keys_button 147static const struct gpio_keys_button
148bcm47xx_buttons_buffalo_whr_g54s[] __initconst = { 148bcm47xx_buttons_buffalo_whr_g54s[] __initconst = {
149 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), 149 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
150 BCM47XX_GPIO_KEY(4, KEY_RESTART), 150 BCM47XX_GPIO_KEY_H(4, KEY_RESTART),
151 BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */ 151 BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
152}; 152};
153 153
diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c
index d85fcdac8bf0..167c42c71e79 100644
--- a/arch/mips/bcm47xx/leds.c
+++ b/arch/mips/bcm47xx/leds.c
@@ -152,11 +152,11 @@ bcm47xx_leds_buffalo_whr_g125[] __initconst = {
152 152
153static const struct gpio_led 153static const struct gpio_led
154bcm47xx_leds_buffalo_whr_g54s[] __initconst = { 154bcm47xx_leds_buffalo_whr_g54s[] __initconst = {
155 BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF), 155 BCM47XX_GPIO_LED(1, "green", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
156 BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), 156 BCM47XX_GPIO_LED(2, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
157 BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF), 157 BCM47XX_GPIO_LED(3, "green", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
158 BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), 158 BCM47XX_GPIO_LED(6, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
159 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), 159 BCM47XX_GPIO_LED(7, "red", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
160}; 160};
161 161
162static const struct gpio_led 162static const struct gpio_led
diff --git a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts
index 0fa3dd1819ff..dda0559cef50 100644
--- a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts
+++ b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts
@@ -180,14 +180,28 @@
180 ethernet@0 { 180 ethernet@0 {
181 phy-handle = <&phy2>; 181 phy-handle = <&phy2>;
182 cavium,alt-phy-handle = <&phy100>; 182 cavium,alt-phy-handle = <&phy100>;
183 rx-delay = <0>;
184 tx-delay = <0>;
185 fixed-link {
186 speed = <1000>;
187 full-duplex;
188 };
183 }; 189 };
184 ethernet@1 { 190 ethernet@1 {
185 phy-handle = <&phy3>; 191 phy-handle = <&phy3>;
186 cavium,alt-phy-handle = <&phy101>; 192 cavium,alt-phy-handle = <&phy101>;
193 rx-delay = <0>;
194 tx-delay = <0>;
195 fixed-link {
196 speed = <1000>;
197 full-duplex;
198 };
187 }; 199 };
188 ethernet@2 { 200 ethernet@2 {
189 phy-handle = <&phy4>; 201 phy-handle = <&phy4>;
190 cavium,alt-phy-handle = <&phy102>; 202 cavium,alt-phy-handle = <&phy102>;
203 rx-delay = <0>;
204 tx-delay = <0>;
191 }; 205 };
192 ethernet@3 { 206 ethernet@3 {
193 compatible = "cavium,octeon-3860-pip-port"; 207 compatible = "cavium,octeon-3860-pip-port";
diff --git a/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts b/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts
index 243e5dc444fb..962f37fbc7db 100644
--- a/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts
+++ b/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts
@@ -33,12 +33,18 @@
33 interface@0 { 33 interface@0 {
34 ethernet@0 { 34 ethernet@0 {
35 phy-handle = <&phy7>; 35 phy-handle = <&phy7>;
36 rx-delay = <0>;
37 tx-delay = <0x10>;
36 }; 38 };
37 ethernet@1 { 39 ethernet@1 {
38 phy-handle = <&phy6>; 40 phy-handle = <&phy6>;
41 rx-delay = <0>;
42 tx-delay = <0x10>;
39 }; 43 };
40 ethernet@2 { 44 ethernet@2 {
41 phy-handle = <&phy5>; 45 phy-handle = <&phy5>;
46 rx-delay = <0>;
47 tx-delay = <0x10>;
42 }; 48 };
43 }; 49 };
44 }; 50 };
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
index ab8362e04461..2e2d45bc850d 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
@@ -31,6 +31,7 @@
31 * network ports from the rest of the cvmx-helper files. 31 * network ports from the rest of the cvmx-helper files.
32 */ 32 */
33 33
34#include <linux/bug.h>
34#include <asm/octeon/octeon.h> 35#include <asm/octeon/octeon.h>
35#include <asm/octeon/cvmx-bootinfo.h> 36#include <asm/octeon/cvmx-bootinfo.h>
36 37
@@ -210,56 +211,18 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
210{ 211{
211 cvmx_helper_link_info_t result; 212 cvmx_helper_link_info_t result;
212 213
214 WARN(!octeon_is_simulation(),
215 "Using deprecated link status - please update your DT");
216
213 /* Unless we fix it later, all links are defaulted to down */ 217 /* Unless we fix it later, all links are defaulted to down */
214 result.u64 = 0; 218 result.u64 = 0;
215 219
216 /* 220 if (octeon_is_simulation()) {
217 * This switch statement should handle all ports that either don't use
218 * Marvell PHYS, or don't support in-band status.
219 */
220 switch (cvmx_sysinfo_get()->board_type) {
221 case CVMX_BOARD_TYPE_SIM:
222 /* The simulator gives you a simulated 1Gbps full duplex link */ 221 /* The simulator gives you a simulated 1Gbps full duplex link */
223 result.s.link_up = 1; 222 result.s.link_up = 1;
224 result.s.full_duplex = 1; 223 result.s.full_duplex = 1;
225 result.s.speed = 1000; 224 result.s.speed = 1000;
226 return result; 225 return result;
227 case CVMX_BOARD_TYPE_EBH3100:
228 case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
229 case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
230 case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
231 /* Port 1 on these boards is always Gigabit */
232 if (ipd_port == 1) {
233 result.s.link_up = 1;
234 result.s.full_duplex = 1;
235 result.s.speed = 1000;
236 return result;
237 }
238 /* Fall through to the generic code below */
239 break;
240 case CVMX_BOARD_TYPE_CUST_NB5:
241 /* Port 1 on these boards is always Gigabit */
242 if (ipd_port == 1) {
243 result.s.link_up = 1;
244 result.s.full_duplex = 1;
245 result.s.speed = 1000;
246 return result;
247 }
248 break;
249 case CVMX_BOARD_TYPE_BBGW_REF:
250 /* Port 1 on these boards is always Gigabit */
251 if (ipd_port == 2) {
252 /* Port 2 is not hooked up */
253 result.u64 = 0;
254 return result;
255 } else {
256 /* Ports 0 and 1 connect to the switch */
257 result.s.link_up = 1;
258 result.s.full_duplex = 1;
259 result.s.speed = 1000;
260 return result;
261 }
262 break;
263 } 226 }
264 227
265 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) 228 if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
@@ -358,45 +321,6 @@ int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
358} 321}
359 322
360/** 323/**
361 * Enable packet input/output from the hardware. This function is
362 * called after by cvmx_helper_packet_hardware_enable() to
363 * perform board specific initialization. For most boards
364 * nothing is needed.
365 *
366 * @interface: Interface to enable
367 *
368 * Returns Zero on success, negative on failure
369 */
370int __cvmx_helper_board_hardware_enable(int interface)
371{
372 if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5) {
373 if (interface == 0) {
374 /* Different config for switch port */
375 cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0);
376 cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
377 /*
378 * Boards with gigabit WAN ports need a
379 * different setting that is compatible with
380 * 100 Mbit settings
381 */
382 cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface),
383 0xc);
384 cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface),
385 0xc);
386 }
387 } else if (cvmx_sysinfo_get()->board_type ==
388 CVMX_BOARD_TYPE_UBNT_E100) {
389 cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0);
390 cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10);
391 cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
392 cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0x10);
393 cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(2, interface), 0);
394 cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(2, interface), 0x10);
395 }
396 return 0;
397}
398
399/**
400 * Get the clock type used for the USB block based on board type. 324 * Get the clock type used for the USB block based on board type.
401 * Used by the USB code for auto configuration of clock type. 325 * Used by the USB code for auto configuration of clock type.
402 * 326 *
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
index 38e0444e57e8..de391541d6f7 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
@@ -30,6 +30,7 @@
30 * Helper functions for common, but complicated tasks. 30 * Helper functions for common, but complicated tasks.
31 * 31 *
32 */ 32 */
33#include <linux/bug.h>
33#include <asm/octeon/octeon.h> 34#include <asm/octeon/octeon.h>
34 35
35#include <asm/octeon/cvmx-config.h> 36#include <asm/octeon/cvmx-config.h>
@@ -43,7 +44,6 @@
43#include <asm/octeon/cvmx-helper-board.h> 44#include <asm/octeon/cvmx-helper-board.h>
44 45
45#include <asm/octeon/cvmx-pip-defs.h> 46#include <asm/octeon/cvmx-pip-defs.h>
46#include <asm/octeon/cvmx-smix-defs.h>
47#include <asm/octeon/cvmx-asxx-defs.h> 47#include <asm/octeon/cvmx-asxx-defs.h>
48 48
49/* Port count per interface */ 49/* Port count per interface */
@@ -317,22 +317,6 @@ cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
317 return CVMX_HELPER_INTERFACE_MODE_DISABLED; 317 return CVMX_HELPER_INTERFACE_MODE_DISABLED;
318 } 318 }
319 319
320 if (interface == 0
321 && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
322 && cvmx_sysinfo_get()->board_rev_major == 1) {
323 /*
324 * Lie about interface type of CN3005 board. This
325 * board has a switch on port 1 like the other
326 * evaluation boards, but it is connected over RGMII
327 * instead of GMII. Report GMII mode so that the
328 * speed is forced to 1 Gbit full duplex. Other than
329 * some initial configuration (which does not use the
330 * output of this function) there is no difference in
331 * setup between GMII and RGMII modes.
332 */
333 return CVMX_HELPER_INTERFACE_MODE_GMII;
334 }
335
336 /* Interface 1 is always disabled on CN31XX and CN30XX */ 320 /* Interface 1 is always disabled on CN31XX and CN30XX */
337 if ((interface == 1) 321 if ((interface == 1)
338 && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) 322 && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
@@ -778,7 +762,6 @@ static int __cvmx_helper_packet_hardware_enable(int interface)
778 result = __cvmx_helper_loop_enable(interface); 762 result = __cvmx_helper_loop_enable(interface);
779 break; 763 break;
780 } 764 }
781 result |= __cvmx_helper_board_hardware_enable(interface);
782 return result; 765 return result;
783} 766}
784 767
@@ -1026,7 +1009,6 @@ int cvmx_helper_initialize_packet_io_global(void)
1026 int result = 0; 1009 int result = 0;
1027 int interface; 1010 int interface;
1028 union cvmx_l2c_cfg l2c_cfg; 1011 union cvmx_l2c_cfg l2c_cfg;
1029 union cvmx_smix_en smix_en;
1030 const int num_interfaces = cvmx_helper_get_number_of_interfaces(); 1012 const int num_interfaces = cvmx_helper_get_number_of_interfaces();
1031 1013
1032 /* 1014 /*
@@ -1046,24 +1028,6 @@ int cvmx_helper_initialize_packet_io_global(void)
1046 l2c_cfg.s.rfb_arb_mode = 0; 1028 l2c_cfg.s.rfb_arb_mode = 0;
1047 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64); 1029 cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
1048 1030
1049 /* Make sure SMI/MDIO is enabled so we can query PHYs */
1050 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
1051 if (!smix_en.s.en) {
1052 smix_en.s.en = 1;
1053 cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
1054 }
1055
1056 /* Newer chips actually have two SMI/MDIO interfaces */
1057 if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
1058 !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
1059 !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
1060 smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
1061 if (!smix_en.s.en) {
1062 smix_en.s.en = 1;
1063 cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
1064 }
1065 }
1066
1067 cvmx_pko_initialize_global(); 1031 cvmx_pko_initialize_global();
1068 for (interface = 0; interface < num_interfaces; interface++) { 1032 for (interface = 0; interface < num_interfaces; interface++) {
1069 result |= cvmx_helper_interface_probe(interface); 1033 result |= cvmx_helper_interface_probe(interface);
@@ -1136,6 +1100,7 @@ cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
1136 if (index == 0) 1100 if (index == 0)
1137 result = __cvmx_helper_rgmii_link_get(ipd_port); 1101 result = __cvmx_helper_rgmii_link_get(ipd_port);
1138 else { 1102 else {
1103 WARN(1, "Using deprecated link status - please update your DT");
1139 result.s.full_duplex = 1; 1104 result.s.full_duplex = 1;
1140 result.s.link_up = 1; 1105 result.s.link_up = 1;
1141 result.s.speed = 1000; 1106 result.s.speed = 1000;
diff --git a/arch/mips/cavium-octeon/oct_ilm.c b/arch/mips/cavium-octeon/oct_ilm.c
index 2d68a39f1443..13f6c7716b1e 100644
--- a/arch/mips/cavium-octeon/oct_ilm.c
+++ b/arch/mips/cavium-octeon/oct_ilm.c
@@ -63,31 +63,11 @@ static int reset_statistics(void *data, u64 value)
63 63
64DEFINE_SIMPLE_ATTRIBUTE(reset_statistics_ops, NULL, reset_statistics, "%llu\n"); 64DEFINE_SIMPLE_ATTRIBUTE(reset_statistics_ops, NULL, reset_statistics, "%llu\n");
65 65
66static int init_debufs(void) 66static void init_debugfs(void)
67{ 67{
68 struct dentry *show_dentry;
69 dir = debugfs_create_dir("oct_ilm", 0); 68 dir = debugfs_create_dir("oct_ilm", 0);
70 if (!dir) { 69 debugfs_create_file("statistics", 0222, dir, NULL, &oct_ilm_ops);
71 pr_err("oct_ilm: failed to create debugfs entry oct_ilm\n"); 70 debugfs_create_file("reset", 0222, dir, NULL, &reset_statistics_ops);
72 return -1;
73 }
74
75 show_dentry = debugfs_create_file("statistics", 0222, dir, NULL,
76 &oct_ilm_ops);
77 if (!show_dentry) {
78 pr_err("oct_ilm: failed to create debugfs entry oct_ilm/statistics\n");
79 return -1;
80 }
81
82 show_dentry = debugfs_create_file("reset", 0222, dir, NULL,
83 &reset_statistics_ops);
84 if (!show_dentry) {
85 pr_err("oct_ilm: failed to create debugfs entry oct_ilm/reset\n");
86 return -1;
87 }
88
89 return 0;
90
91} 71}
92 72
93static void init_latency_info(struct latency_info *li, int startup) 73static void init_latency_info(struct latency_info *li, int startup)
@@ -169,11 +149,7 @@ static __init int oct_ilm_module_init(void)
169 int rc; 149 int rc;
170 int irq = OCTEON_IRQ_TIMER0 + TIMER_NUM; 150 int irq = OCTEON_IRQ_TIMER0 + TIMER_NUM;
171 151
172 rc = init_debufs(); 152 init_debugfs();
173 if (rc) {
174 WARN(1, "Could not create debugfs entries");
175 return rc;
176 }
177 153
178 rc = request_irq(irq, cvm_oct_ciu_timer_interrupt, IRQF_NO_THREAD, 154 rc = request_irq(irq, cvm_oct_ciu_timer_interrupt, IRQF_NO_THREAD,
179 "oct_ilm", 0); 155 "oct_ilm", 0);
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 1f9ba60f7375..51685f893eab 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -458,6 +458,23 @@ static bool __init octeon_has_88e1145(void)
458 !OCTEON_IS_MODEL(OCTEON_CN56XX); 458 !OCTEON_IS_MODEL(OCTEON_CN56XX);
459} 459}
460 460
461static bool __init octeon_has_fixed_link(int ipd_port)
462{
463 switch (cvmx_sysinfo_get()->board_type) {
464 case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
465 case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
466 case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
467 case CVMX_BOARD_TYPE_CUST_NB5:
468 case CVMX_BOARD_TYPE_EBH3100:
469 /* Port 1 on these boards is always gigabit. */
470 return ipd_port == 1;
471 case CVMX_BOARD_TYPE_BBGW_REF:
472 /* Ports 0 and 1 connect to the switch. */
473 return ipd_port == 0 || ipd_port == 1;
474 }
475 return false;
476}
477
461static void __init octeon_fdt_set_phy(int eth, int phy_addr) 478static void __init octeon_fdt_set_phy(int eth, int phy_addr)
462{ 479{
463 const __be32 *phy_handle; 480 const __be32 *phy_handle;
@@ -586,12 +603,52 @@ static void __init octeon_fdt_rm_ethernet(int node)
586 fdt_nop_node(initial_boot_params, node); 603 fdt_nop_node(initial_boot_params, node);
587} 604}
588 605
606static void __init _octeon_rx_tx_delay(int eth, int rx_delay, int tx_delay)
607{
608 fdt_setprop_inplace_cell(initial_boot_params, eth, "rx-delay",
609 rx_delay);
610 fdt_setprop_inplace_cell(initial_boot_params, eth, "tx-delay",
611 tx_delay);
612}
613
614static void __init octeon_rx_tx_delay(int eth, int iface, int port)
615{
616 switch (cvmx_sysinfo_get()->board_type) {
617 case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
618 if (iface == 0) {
619 if (port == 0) {
620 /*
621 * Boards with gigabit WAN ports need a
622 * different setting that is compatible with
623 * 100 Mbit settings
624 */
625 _octeon_rx_tx_delay(eth, 0xc, 0x0c);
626 return;
627 } else if (port == 1) {
628 /* Different config for switch port. */
629 _octeon_rx_tx_delay(eth, 0x0, 0x0);
630 return;
631 }
632 }
633 break;
634 case CVMX_BOARD_TYPE_UBNT_E100:
635 if (iface == 0 && port <= 2) {
636 _octeon_rx_tx_delay(eth, 0x0, 0x10);
637 return;
638 }
639 break;
640 }
641 fdt_nop_property(initial_boot_params, eth, "rx-delay");
642 fdt_nop_property(initial_boot_params, eth, "tx-delay");
643}
644
589static void __init octeon_fdt_pip_port(int iface, int i, int p, int max) 645static void __init octeon_fdt_pip_port(int iface, int i, int p, int max)
590{ 646{
591 char name_buffer[20]; 647 char name_buffer[20];
592 int eth; 648 int eth;
593 int phy_addr; 649 int phy_addr;
594 int ipd_port; 650 int ipd_port;
651 int fixed_link;
595 652
596 snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p); 653 snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p);
597 eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer); 654 eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer);
@@ -609,6 +666,13 @@ static void __init octeon_fdt_pip_port(int iface, int i, int p, int max)
609 666
610 phy_addr = cvmx_helper_board_get_mii_address(ipd_port); 667 phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
611 octeon_fdt_set_phy(eth, phy_addr); 668 octeon_fdt_set_phy(eth, phy_addr);
669
670 fixed_link = fdt_subnode_offset(initial_boot_params, eth, "fixed-link");
671 if (fixed_link < 0)
672 WARN_ON(octeon_has_fixed_link(ipd_port));
673 else if (!octeon_has_fixed_link(ipd_port))
674 fdt_nop_node(initial_boot_params, fixed_link);
675 octeon_rx_tx_delay(eth, i, p);
612} 676}
613 677
614static void __init octeon_fdt_pip_iface(int pip, int idx) 678static void __init octeon_fdt_pip_iface(int pip, int idx)
diff --git a/arch/mips/configs/xway_defconfig b/arch/mips/configs/xway_defconfig
index c3cac29e8414..2bb02ea9fb4e 100644
--- a/arch/mips/configs/xway_defconfig
+++ b/arch/mips/configs/xway_defconfig
@@ -13,7 +13,6 @@ CONFIG_EMBEDDED=y
13# CONFIG_COMPAT_BRK is not set 13# CONFIG_COMPAT_BRK is not set
14CONFIG_LANTIQ=y 14CONFIG_LANTIQ=y
15CONFIG_PCI_LANTIQ=y 15CONFIG_PCI_LANTIQ=y
16CONFIG_XRX200_PHY_FW=y
17CONFIG_CPU_MIPS32_R2=y 16CONFIG_CPU_MIPS32_R2=y
18CONFIG_MIPS_VPE_LOADER=y 17CONFIG_MIPS_VPE_LOADER=y
19CONFIG_NR_CPUS=2 18CONFIG_NR_CPUS=2
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index f15d5db5dd67..87b86cdf126a 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -3,7 +3,6 @@ generated-y += syscall_table_32_o32.h
3generated-y += syscall_table_64_n32.h 3generated-y += syscall_table_64_n32.h
4generated-y += syscall_table_64_n64.h 4generated-y += syscall_table_64_n64.h
5generated-y += syscall_table_64_o32.h 5generated-y += syscall_table_64_o32.h
6generic-(CONFIG_GENERIC_CSUM) += checksum.h
7generic-y += current.h 6generic-y += current.h
8generic-y += device.h 7generic-y += device.h
9generic-y += dma-contiguous.h 8generic-y += dma-contiguous.h
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
index b7f6ac5e513c..b865e317a14f 100644
--- a/arch/mips/include/asm/barrier.h
+++ b/arch/mips/include/asm/barrier.h
@@ -105,6 +105,20 @@
105 */ 105 */
106#define STYPE_SYNC_MB 0x10 106#define STYPE_SYNC_MB 0x10
107 107
108/*
109 * stype 0x14 - A completion barrier specific to global invalidations
110 *
111 * When a sync instruction of this type completes any preceding GINVI or GINVT
112 * operation has been globalized & completed on all coherent CPUs. Anything
113 * that the GINV* instruction should invalidate will have been invalidated on
114 * all coherent CPUs when this instruction completes. It is implementation
115 * specific whether the GINV* instructions themselves will ensure completion,
116 * or this sync type will.
117 *
118 * In systems implementing global invalidates (ie. with Config5.GI == 2 or 3)
119 * this sync type also requires that previous SYNCI operations have completed.
120 */
121#define STYPE_GINV 0x14
108 122
109#ifdef CONFIG_CPU_HAS_SYNC 123#ifdef CONFIG_CPU_HAS_SYNC
110#define __sync() \ 124#define __sync() \
@@ -258,6 +272,11 @@
258#define loongson_llsc_mb() do { } while (0) 272#define loongson_llsc_mb() do { } while (0)
259#endif 273#endif
260 274
275static inline void sync_ginv(void)
276{
277 asm volatile("sync\t%0" :: "i"(STYPE_GINV));
278}
279
261#include <asm-generic/barrier.h> 280#include <asm-generic/barrier.h>
262 281
263#endif /* __ASM_BARRIER_H */ 282#endif /* __ASM_BARRIER_H */
diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h
index 4812d1fed0c2..d687b40b9fbb 100644
--- a/arch/mips/include/asm/cacheflush.h
+++ b/arch/mips/include/asm/cacheflush.h
@@ -25,7 +25,6 @@
25 * 25 *
26 * MIPS specific flush operations: 26 * MIPS specific flush operations:
27 * 27 *
28 * - flush_cache_sigtramp() flush signal trampoline
29 * - flush_icache_all() flush the entire instruction cache 28 * - flush_icache_all() flush the entire instruction cache
30 * - flush_data_cache_page() flushes a page from the data cache 29 * - flush_data_cache_page() flushes a page from the data cache
31 * - __flush_icache_user_range(start, end) flushes range of user instructions 30 * - __flush_icache_user_range(start, end) flushes range of user instructions
@@ -110,7 +109,6 @@ extern void copy_from_user_page(struct vm_area_struct *vma,
110 struct page *page, unsigned long vaddr, void *dst, const void *src, 109 struct page *page, unsigned long vaddr, void *dst, const void *src,
111 unsigned long len); 110 unsigned long len);
112 111
113extern void (*flush_cache_sigtramp)(unsigned long addr);
114extern void (*flush_icache_all)(void); 112extern void (*flush_icache_all)(void);
115extern void (*local_flush_data_cache_page)(void * addr); 113extern void (*local_flush_data_cache_page)(void * addr);
116extern void (*flush_data_cache_page)(unsigned long addr); 114extern void (*flush_data_cache_page)(unsigned long addr);
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
index 638de0c25249..f345a873742d 100644
--- a/arch/mips/include/asm/cmpxchg.h
+++ b/arch/mips/include/asm/cmpxchg.h
@@ -36,6 +36,8 @@
36 */ 36 */
37extern unsigned long __cmpxchg_called_with_bad_pointer(void) 37extern unsigned long __cmpxchg_called_with_bad_pointer(void)
38 __compiletime_error("Bad argument size for cmpxchg"); 38 __compiletime_error("Bad argument size for cmpxchg");
39extern unsigned long __cmpxchg64_unsupported(void)
40 __compiletime_error("cmpxchg64 not available; cpu_has_64bits may be false");
39extern unsigned long __xchg_called_with_bad_pointer(void) 41extern unsigned long __xchg_called_with_bad_pointer(void)
40 __compiletime_error("Bad argument size for xchg"); 42 __compiletime_error("Bad argument size for xchg");
41 43
@@ -204,12 +206,102 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
204 cmpxchg((ptr), (o), (n)); \ 206 cmpxchg((ptr), (o), (n)); \
205 }) 207 })
206#else 208#else
207#include <asm-generic/cmpxchg-local.h> 209
208#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) 210# include <asm-generic/cmpxchg-local.h>
209#ifndef CONFIG_SMP 211# define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
210#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n)) 212
211#endif 213# ifdef CONFIG_SMP
212#endif 214
215static inline unsigned long __cmpxchg64(volatile void *ptr,
216 unsigned long long old,
217 unsigned long long new)
218{
219 unsigned long long tmp, ret;
220 unsigned long flags;
221
222 /*
223 * The assembly below has to combine 32 bit values into a 64 bit
224 * register, and split 64 bit values from one register into two. If we
225 * were to take an interrupt in the middle of this we'd only save the
226 * least significant 32 bits of each register & probably clobber the
227 * most significant 32 bits of the 64 bit values we're using. In order
228 * to avoid this we must disable interrupts.
229 */
230 local_irq_save(flags);
231
232 asm volatile(
233 " .set push \n"
234 " .set " MIPS_ISA_ARCH_LEVEL " \n"
235 /* Load 64 bits from ptr */
236 "1: lld %L0, %3 # __cmpxchg64 \n"
237 /*
238 * Split the 64 bit value we loaded into the 2 registers that hold the
239 * ret variable.
240 */
241 " dsra %M0, %L0, 32 \n"
242 " sll %L0, %L0, 0 \n"
243 /*
244 * Compare ret against old, breaking out of the loop if they don't
245 * match.
246 */
247 " bne %M0, %M4, 2f \n"
248 " bne %L0, %L4, 2f \n"
249 /*
250 * Combine the 32 bit halves from the 2 registers that hold the new
251 * variable into a single 64 bit register.
252 */
253# if MIPS_ISA_REV >= 2
254 " move %L1, %L5 \n"
255 " dins %L1, %M5, 32, 32 \n"
256# else
257 " dsll %L1, %L5, 32 \n"
258 " dsrl %L1, %L1, 32 \n"
259 " .set noat \n"
260 " dsll $at, %M5, 32 \n"
261 " or %L1, %L1, $at \n"
262 " .set at \n"
263# endif
264 /* Attempt to store new at ptr */
265 " scd %L1, %2 \n"
266 /* If we failed, loop! */
267 "\t" __scbeqz " %L1, 1b \n"
268 " .set pop \n"
269 "2: \n"
270 : "=&r"(ret),
271 "=&r"(tmp),
272 "=" GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr)
273 : GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr),
274 "r" (old),
275 "r" (new)
276 : "memory");
277
278 local_irq_restore(flags);
279 return ret;
280}
281
282# define cmpxchg64(ptr, o, n) ({ \
283 unsigned long long __old = (__typeof__(*(ptr)))(o); \
284 unsigned long long __new = (__typeof__(*(ptr)))(n); \
285 __typeof__(*(ptr)) __res; \
286 \
287 /* \
288 * We can only use cmpxchg64 if we know that the CPU supports \
289 * 64-bits, ie. lld & scd. Our call to __cmpxchg64_unsupported \
290 * will cause a build error unless cpu_has_64bits is a \
291 * compile-time constant 1. \
292 */ \
293 if (cpu_has_64bits && kernel_uses_llsc) \
294 __res = __cmpxchg64((ptr), __old, __new); \
295 else \
296 __res = __cmpxchg64_unsupported(); \
297 \
298 __res; \
299})
300
301# else /* !CONFIG_SMP */
302# define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
303# endif /* !CONFIG_SMP */
304#endif /* !CONFIG_64BIT */
213 305
214#undef __scbeqz 306#undef __scbeqz
215 307
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 701e525641b8..6998a9796499 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -591,6 +591,19 @@
591#endif /* CONFIG_MIPS_MT_SMP */ 591#endif /* CONFIG_MIPS_MT_SMP */
592 592
593/* 593/*
594 * We only enable MMID support for configurations which natively support 64 bit
595 * atomics because getting good performance from the allocator relies upon
596 * efficient atomic64_*() functions.
597 */
598#ifndef cpu_has_mmid
599# ifdef CONFIG_GENERIC_ATOMIC64
600# define cpu_has_mmid 0
601# else
602# define cpu_has_mmid __isa_ge_and_opt(6, MIPS_CPU_MMID)
603# endif
604#endif
605
606/*
594 * Guest capabilities 607 * Guest capabilities
595 */ 608 */
596#ifndef cpu_guest_has_conf1 609#ifndef cpu_guest_has_conf1
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 532b49b1dbb3..6ad7d3cabd91 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -422,6 +422,7 @@ enum cpu_type_enum {
422 MBIT_ULL(55) /* CPU shares FTLB entries with another */ 422 MBIT_ULL(55) /* CPU shares FTLB entries with another */
423#define MIPS_CPU_MT_PER_TC_PERF_COUNTERS \ 423#define MIPS_CPU_MT_PER_TC_PERF_COUNTERS \
424 MBIT_ULL(56) /* CPU has perf counters implemented per TC (MIPSMT ASE) */ 424 MBIT_ULL(56) /* CPU has perf counters implemented per TC (MIPSMT ASE) */
425#define MIPS_CPU_MMID MBIT_ULL(57) /* CPU supports MemoryMapIDs */
425 426
426/* 427/*
427 * CPU ASE encodings 428 * CPU ASE encodings
diff --git a/arch/mips/include/asm/ginvt.h b/arch/mips/include/asm/ginvt.h
new file mode 100644
index 000000000000..49c6dbe37338
--- /dev/null
+++ b/arch/mips/include/asm/ginvt.h
@@ -0,0 +1,56 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __MIPS_ASM_GINVT_H__
3#define __MIPS_ASM_GINVT_H__
4
5#include <asm/mipsregs.h>
6
7enum ginvt_type {
8 GINVT_FULL,
9 GINVT_VA,
10 GINVT_MMID,
11};
12
13#ifdef TOOLCHAIN_SUPPORTS_GINV
14# define _ASM_SET_GINV ".set ginv\n"
15#else
16_ASM_MACRO_1R1I(ginvt, rs, type,
17 _ASM_INSN_IF_MIPS(0x7c0000bd | (__rs << 21) | (\\type << 8))
18 _ASM_INSN32_IF_MM(0x0000717c | (__rs << 16) | (\\type << 9)));
19# define _ASM_SET_GINV
20#endif
21
22static inline void ginvt(unsigned long addr, enum ginvt_type type)
23{
24 asm volatile(
25 ".set push\n"
26 _ASM_SET_GINV
27 " ginvt %0, %1\n"
28 ".set pop"
29 : /* no outputs */
30 : "r"(addr), "i"(type)
31 : "memory");
32}
33
34static inline void ginvt_full(void)
35{
36 ginvt(0, GINVT_FULL);
37}
38
39static inline void ginvt_va(unsigned long addr)
40{
41 addr &= PAGE_MASK << 1;
42 ginvt(addr, GINVT_VA);
43}
44
45static inline void ginvt_mmid(void)
46{
47 ginvt(0, GINVT_MMID);
48}
49
50static inline void ginvt_va_mmid(unsigned long addr)
51{
52 addr &= PAGE_MASK << 1;
53 ginvt(addr, GINVT_VA | GINVT_MMID);
54}
55
56#endif /* __MIPS_ASM_GINVT_H__ */
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h
index 9d3610be2323..f0b862a83816 100644
--- a/arch/mips/include/asm/irqflags.h
+++ b/arch/mips/include/asm/irqflags.h
@@ -41,7 +41,7 @@ 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) 44#if defined(CONFIG_CPU_LOONGSON3) || defined (CONFIG_CPU_LOONGSON1)
45 " mfc0 %[flags], $12 \n" 45 " mfc0 %[flags], $12 \n"
46 " di \n" 46 " di \n"
47#else 47#else
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
index 73dcd63b8243..47e8827e9564 100644
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -178,8 +178,4 @@ static inline u32 ath79_reset_rr(unsigned reg)
178void ath79_device_reset_set(u32 mask); 178void ath79_device_reset_set(u32 mask);
179void ath79_device_reset_clear(u32 mask); 179void ath79_device_reset_clear(u32 mask);
180 180
181void ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3);
182void ath79_misc_irq_init(void __iomem *regs, int irq,
183 int irq_base, bool is_ar71xx);
184
185#endif /* __ASM_MACH_ATH79_H */ 181#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/include/asm/mach-ip27/irq.h b/arch/mips/include/asm/mach-ip27/irq.h
index b0b7261ff3ad..fd91c58aaf7d 100644
--- a/arch/mips/include/asm/mach-ip27/irq.h
+++ b/arch/mips/include/asm/mach-ip27/irq.h
@@ -10,13 +10,15 @@
10#ifndef __ASM_MACH_IP27_IRQ_H 10#ifndef __ASM_MACH_IP27_IRQ_H
11#define __ASM_MACH_IP27_IRQ_H 11#define __ASM_MACH_IP27_IRQ_H
12 12
13/*
14 * A hardwired interrupt number is completely stupid for this system - a
15 * large configuration might have thousands if not tenthousands of
16 * interrupts.
17 */
18#define NR_IRQS 256 13#define NR_IRQS 256
19 14
20#include_next <irq.h> 15#include_next <irq.h>
21 16
17#define IP27_HUB_PEND0_IRQ (MIPS_CPU_IRQ_BASE + 2)
18#define IP27_HUB_PEND1_IRQ (MIPS_CPU_IRQ_BASE + 3)
19#define IP27_RT_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 4)
20
21#define IP27_HUB_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
22#define IP27_HUB_IRQ_COUNT 128
23
22#endif /* __ASM_MACH_IP27_IRQ_H */ 24#endif /* __ASM_MACH_IP27_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ip27/mmzone.h b/arch/mips/include/asm/mach-ip27/mmzone.h
index 2ed3094dee07..1cd6a23a84f2 100644
--- a/arch/mips/include/asm/mach-ip27/mmzone.h
+++ b/arch/mips/include/asm/mach-ip27/mmzone.h
@@ -8,20 +8,11 @@
8 8
9#define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr)) 9#define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr))
10 10
11#define LEVELS_PER_SLICE 128
12
13struct slice_data {
14 unsigned long irq_enable_mask[2];
15 int level_to_irq[LEVELS_PER_SLICE];
16};
17
18struct hub_data { 11struct hub_data {
19 kern_vars_t kern_vars; 12 kern_vars_t kern_vars;
20 DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW); 13 DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
21 cpumask_t h_cpus; 14 cpumask_t h_cpus;
22 unsigned long slice_map; 15 unsigned long slice_map;
23 unsigned long irq_alloc_mask[2];
24 struct slice_data slice[2];
25}; 16};
26 17
27struct node_data { 18struct node_data {
diff --git a/arch/mips/include/asm/mach-loongson32/platform.h b/arch/mips/include/asm/mach-loongson32/platform.h
index 8f8fa43ba095..15d1de2300fe 100644
--- a/arch/mips/include/asm/mach-loongson32/platform.h
+++ b/arch/mips/include/asm/mach-loongson32/platform.h
@@ -17,19 +17,15 @@
17 17
18extern struct platform_device ls1x_uart_pdev; 18extern struct platform_device ls1x_uart_pdev;
19extern struct platform_device ls1x_cpufreq_pdev; 19extern struct platform_device ls1x_cpufreq_pdev;
20extern struct platform_device ls1x_dma_pdev;
21extern struct platform_device ls1x_eth0_pdev; 20extern struct platform_device ls1x_eth0_pdev;
22extern struct platform_device ls1x_eth1_pdev; 21extern struct platform_device ls1x_eth1_pdev;
23extern struct platform_device ls1x_ehci_pdev; 22extern struct platform_device ls1x_ehci_pdev;
24extern struct platform_device ls1x_gpio0_pdev; 23extern struct platform_device ls1x_gpio0_pdev;
25extern struct platform_device ls1x_gpio1_pdev; 24extern struct platform_device ls1x_gpio1_pdev;
26extern struct platform_device ls1x_nand_pdev;
27extern struct platform_device ls1x_rtc_pdev; 25extern struct platform_device ls1x_rtc_pdev;
28extern struct platform_device ls1x_wdt_pdev; 26extern struct platform_device ls1x_wdt_pdev;
29 27
30void __init ls1x_clk_init(void); 28void __init ls1x_clk_init(void);
31void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata);
32void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata);
33void __init ls1x_rtc_set_extclk(struct platform_device *pdev); 29void __init ls1x_rtc_set_extclk(struct platform_device *pdev);
34void __init ls1x_serial_set_uartclk(struct platform_device *pdev); 30void __init ls1x_serial_set_uartclk(struct platform_device *pdev);
35 31
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 402b80af91aa..1e6966e8527e 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -667,6 +667,7 @@
667#define MIPS_CONF5_FRE (_ULCAST_(1) << 8) 667#define MIPS_CONF5_FRE (_ULCAST_(1) << 8)
668#define MIPS_CONF5_UFE (_ULCAST_(1) << 9) 668#define MIPS_CONF5_UFE (_ULCAST_(1) << 9)
669#define MIPS_CONF5_CA2 (_ULCAST_(1) << 14) 669#define MIPS_CONF5_CA2 (_ULCAST_(1) << 14)
670#define MIPS_CONF5_MI (_ULCAST_(1) << 17)
670#define MIPS_CONF5_CRCP (_ULCAST_(1) << 18) 671#define MIPS_CONF5_CRCP (_ULCAST_(1) << 18)
671#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) 672#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27)
672#define MIPS_CONF5_EVA (_ULCAST_(1) << 28) 673#define MIPS_CONF5_EVA (_ULCAST_(1) << 28)
@@ -1247,6 +1248,13 @@ __asm__(".macro parse_r var r\n\t"
1247 ENC \ 1248 ENC \
1248 ".endm") 1249 ".endm")
1249 1250
1251/* Instructions with 1 register operand & 1 immediate operand */
1252#define _ASM_MACRO_1R1I(OP, R1, I2, ENC) \
1253 __asm__(".macro " #OP " " #R1 ", " #I2 "\n\t" \
1254 "parse_r __" #R1 ", \\" #R1 "\n\t" \
1255 ENC \
1256 ".endm")
1257
1250/* Instructions with 2 register operands */ 1258/* Instructions with 2 register operands */
1251#define _ASM_MACRO_2R(OP, R1, R2, ENC) \ 1259#define _ASM_MACRO_2R(OP, R1, R2, ENC) \
1252 __asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \ 1260 __asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \
@@ -1603,6 +1611,9 @@ do { \
1603#define read_c0_xcontextconfig() __read_ulong_c0_register($4, 3) 1611#define read_c0_xcontextconfig() __read_ulong_c0_register($4, 3)
1604#define write_c0_xcontextconfig(val) __write_ulong_c0_register($4, 3, val) 1612#define write_c0_xcontextconfig(val) __write_ulong_c0_register($4, 3, val)
1605 1613
1614#define read_c0_memorymapid() __read_32bit_c0_register($4, 5)
1615#define write_c0_memorymapid(val) __write_32bit_c0_register($4, 5, val)
1616
1606#define read_c0_pagemask() __read_32bit_c0_register($5, 0) 1617#define read_c0_pagemask() __read_32bit_c0_register($5, 0)
1607#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) 1618#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
1608 1619
diff --git a/arch/mips/include/asm/mmu.h b/arch/mips/include/asm/mmu.h
index 88a108ce62c1..5df0238f639b 100644
--- a/arch/mips/include/asm/mmu.h
+++ b/arch/mips/include/asm/mmu.h
@@ -7,7 +7,11 @@
7#include <linux/wait.h> 7#include <linux/wait.h>
8 8
9typedef struct { 9typedef struct {
10 u64 asid[NR_CPUS]; 10 union {
11 u64 asid[NR_CPUS];
12 atomic64_t mmid;
13 };
14
11 void *vdso; 15 void *vdso;
12 16
13 /* lock to be held whilst modifying fp_bd_emupage_allocmap */ 17 /* lock to be held whilst modifying fp_bd_emupage_allocmap */
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index a589585be21b..cddead91acd4 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -17,8 +17,10 @@
17#include <linux/smp.h> 17#include <linux/smp.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19 19
20#include <asm/barrier.h>
20#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
21#include <asm/dsemul.h> 22#include <asm/dsemul.h>
23#include <asm/ginvt.h>
22#include <asm/hazards.h> 24#include <asm/hazards.h>
23#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
24#include <asm-generic/mm_hooks.h> 26#include <asm-generic/mm_hooks.h>
@@ -73,6 +75,19 @@ extern unsigned long pgd_current[];
73#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ 75#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
74 76
75/* 77/*
78 * The ginvt instruction will invalidate wired entries when its type field
79 * targets anything other than the entire TLB. That means that if we were to
80 * allow the kernel to create wired entries with the MMID of current->active_mm
81 * then those wired entries could be invalidated when we later use ginvt to
82 * invalidate TLB entries with that MMID.
83 *
84 * In order to prevent ginvt from trashing wired entries, we reserve one MMID
85 * for use by the kernel when creating wired entries. This MMID will never be
86 * assigned to a struct mm, and we'll never target it with a ginvt instruction.
87 */
88#define MMID_KERNEL_WIRED 0
89
90/*
76 * All unused by hardware upper bits will be considered 91 * All unused by hardware upper bits will be considered
77 * as a software asid extension. 92 * as a software asid extension.
78 */ 93 */
@@ -88,7 +103,23 @@ static inline u64 asid_first_version(unsigned int cpu)
88 return ~asid_version_mask(cpu) + 1; 103 return ~asid_version_mask(cpu) + 1;
89} 104}
90 105
91#define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) 106static inline u64 cpu_context(unsigned int cpu, const struct mm_struct *mm)
107{
108 if (cpu_has_mmid)
109 return atomic64_read(&mm->context.mmid);
110
111 return mm->context.asid[cpu];
112}
113
114static inline void set_cpu_context(unsigned int cpu,
115 struct mm_struct *mm, u64 ctx)
116{
117 if (cpu_has_mmid)
118 atomic64_set(&mm->context.mmid, ctx);
119 else
120 mm->context.asid[cpu] = ctx;
121}
122
92#define asid_cache(cpu) (cpu_data[cpu].asid_cache) 123#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
93#define cpu_asid(cpu, mm) \ 124#define cpu_asid(cpu, mm) \
94 (cpu_context((cpu), (mm)) & cpu_asid_mask(&cpu_data[cpu])) 125 (cpu_context((cpu), (mm)) & cpu_asid_mask(&cpu_data[cpu]))
@@ -97,21 +128,9 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
97{ 128{
98} 129}
99 130
100 131extern void get_new_mmu_context(struct mm_struct *mm);
101/* Normal, classic MIPS get_new_mmu_context */ 132extern void check_mmu_context(struct mm_struct *mm);
102static inline void 133extern void check_switch_mmu_context(struct mm_struct *mm);
103get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
104{
105 u64 asid = asid_cache(cpu);
106
107 if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) {
108 if (cpu_has_vtag_icache)
109 flush_icache_all();
110 local_flush_tlb_all(); /* start new asid cycle */
111 }
112
113 cpu_context(cpu, mm) = asid_cache(cpu) = asid;
114}
115 134
116/* 135/*
117 * Initialize the context related info for a new mm_struct 136 * Initialize the context related info for a new mm_struct
@@ -122,8 +141,12 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
122{ 141{
123 int i; 142 int i;
124 143
125 for_each_possible_cpu(i) 144 if (cpu_has_mmid) {
126 cpu_context(i, mm) = 0; 145 set_cpu_context(0, mm, 0);
146 } else {
147 for_each_possible_cpu(i)
148 set_cpu_context(i, mm, 0);
149 }
127 150
128 mm->context.bd_emupage_allocmap = NULL; 151 mm->context.bd_emupage_allocmap = NULL;
129 spin_lock_init(&mm->context.bd_emupage_lock); 152 spin_lock_init(&mm->context.bd_emupage_lock);
@@ -140,11 +163,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
140 local_irq_save(flags); 163 local_irq_save(flags);
141 164
142 htw_stop(); 165 htw_stop();
143 /* Check if our ASID is of an older version and thus invalid */ 166 check_switch_mmu_context(next);
144 if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & asid_version_mask(cpu))
145 get_new_mmu_context(next, cpu);
146 write_c0_entryhi(cpu_asid(cpu, next));
147 TLBMISS_HANDLER_SETUP_PGD(next->pgd);
148 167
149 /* 168 /*
150 * Mark current->active_mm as not "active" anymore. 169 * Mark current->active_mm as not "active" anymore.
@@ -166,55 +185,55 @@ static inline void destroy_context(struct mm_struct *mm)
166 dsemul_mm_cleanup(mm); 185 dsemul_mm_cleanup(mm);
167} 186}
168 187
188#define activate_mm(prev, next) switch_mm(prev, next, current)
169#define deactivate_mm(tsk, mm) do { } while (0) 189#define deactivate_mm(tsk, mm) do { } while (0)
170 190
171/*
172 * After we have set current->mm to a new value, this activates
173 * the context for the new mm so we see the new mappings.
174 */
175static inline void
176activate_mm(struct mm_struct *prev, struct mm_struct *next)
177{
178 unsigned long flags;
179 unsigned int cpu = smp_processor_id();
180
181 local_irq_save(flags);
182
183 htw_stop();
184 /* Unconditionally get a new ASID. */
185 get_new_mmu_context(next, cpu);
186
187 write_c0_entryhi(cpu_asid(cpu, next));
188 TLBMISS_HANDLER_SETUP_PGD(next->pgd);
189
190 /* mark mmu ownership change */
191 cpumask_clear_cpu(cpu, mm_cpumask(prev));
192 cpumask_set_cpu(cpu, mm_cpumask(next));
193 htw_start();
194
195 local_irq_restore(flags);
196}
197
198/*
199 * If mm is currently active_mm, we can't really drop it. Instead,
200 * we will get a new one for it.
201 */
202static inline void 191static inline void
203drop_mmu_context(struct mm_struct *mm, unsigned cpu) 192drop_mmu_context(struct mm_struct *mm)
204{ 193{
205 unsigned long flags; 194 unsigned long flags;
195 unsigned int cpu;
196 u32 old_mmid;
197 u64 ctx;
206 198
207 local_irq_save(flags); 199 local_irq_save(flags);
208 htw_stop();
209 200
210 if (cpumask_test_cpu(cpu, mm_cpumask(mm))) { 201 cpu = smp_processor_id();
211 get_new_mmu_context(mm, cpu); 202 ctx = cpu_context(cpu, mm);
203
204 if (!ctx) {
205 /* no-op */
206 } else if (cpu_has_mmid) {
207 /*
208 * Globally invalidating TLB entries associated with the MMID
209 * is pretty cheap using the GINVT instruction, so we'll do
210 * that rather than incur the overhead of allocating a new
211 * MMID. The latter would be especially difficult since MMIDs
212 * are global & other CPUs may be actively using ctx.
213 */
214 htw_stop();
215 old_mmid = read_c0_memorymapid();
216 write_c0_memorymapid(ctx & cpu_asid_mask(&cpu_data[cpu]));
217 mtc0_tlbw_hazard();
218 ginvt_mmid();
219 sync_ginv();
220 write_c0_memorymapid(old_mmid);
221 instruction_hazard();
222 htw_start();
223 } else if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
224 /*
225 * mm is currently active, so we can't really drop it.
226 * Instead we bump the ASID.
227 */
228 htw_stop();
229 get_new_mmu_context(mm);
212 write_c0_entryhi(cpu_asid(cpu, mm)); 230 write_c0_entryhi(cpu_asid(cpu, mm));
231 htw_start();
213 } else { 232 } else {
214 /* will get a new context next time */ 233 /* will get a new context next time */
215 cpu_context(cpu, mm) = 0; 234 set_cpu_context(cpu, mm, 0);
216 } 235 }
217 htw_start(); 236
218 local_irq_restore(flags); 237 local_irq_restore(flags);
219} 238}
220 239
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h
index b4d19c21b62c..d7fdcf0a0088 100644
--- a/arch/mips/include/asm/octeon/cvmx-helper-board.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h
@@ -119,18 +119,6 @@ extern cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port);
119extern int __cvmx_helper_board_interface_probe(int interface, 119extern int __cvmx_helper_board_interface_probe(int interface,
120 int supported_ports); 120 int supported_ports);
121 121
122/**
123 * Enable packet input/output from the hardware. This function is
124 * called after by cvmx_helper_packet_hardware_enable() to
125 * perform board specific initialization. For most boards
126 * nothing is needed.
127 *
128 * @interface: Interface to enable
129 *
130 * Returns Zero on success, negative on failure
131 */
132extern int __cvmx_helper_board_hardware_enable(int interface);
133
134enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void); 122enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void);
135 123
136#endif /* __CVMX_HELPER_BOARD_H__ */ 124#endif /* __CVMX_HELPER_BOARD_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
deleted file mode 100644
index 7a928230b0c0..000000000000
--- a/arch/mips/include/asm/octeon/cvmx-smix-defs.h
+++ /dev/null
@@ -1,276 +0,0 @@
1/***********************license start***************
2 * Author: Cavium Networks
3 *
4 * Contact: support@caviumnetworks.com
5 * This file is part of the OCTEON SDK
6 *
7 * Copyright (c) 2003-2012 Cavium Networks
8 *
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
11 * published by the Free Software Foundation.
12 *
13 * This file is distributed in the hope that it will be useful, but
14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16 * NONINFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this file; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * or visit http://www.gnu.org/licenses/.
23 *
24 * This file may also be available under a different license from Cavium.
25 * Contact Cavium Networks for more information
26 ***********************license end**************************************/
27
28#ifndef __CVMX_SMIX_DEFS_H__
29#define __CVMX_SMIX_DEFS_H__
30
31static inline uint64_t CVMX_SMIX_CLK(unsigned long offset)
32{
33 switch (cvmx_get_octeon_family()) {
34 case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
35 case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
36 case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
37 case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
38 case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
39 return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
40 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
41 case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
42 case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
43 case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
44 case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
45 case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
46 return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
47 case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
48 return CVMX_ADD_IO_SEG(0x0001180000003818ull) + (offset) * 128;
49 }
50 return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
51}
52
53static inline uint64_t CVMX_SMIX_CMD(unsigned long offset)
54{
55 switch (cvmx_get_octeon_family()) {
56 case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
57 case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
58 case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
59 case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
60 case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
61 return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
62 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
63 case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
64 case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
65 case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
66 case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
67 case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
68 return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
69 case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
70 return CVMX_ADD_IO_SEG(0x0001180000003800ull) + (offset) * 128;
71 }
72 return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
73}
74
75static inline uint64_t CVMX_SMIX_EN(unsigned long offset)
76{
77 switch (cvmx_get_octeon_family()) {
78 case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
79 case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
80 case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
81 case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
82 case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
83 return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
84 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
85 case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
86 case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
87 case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
88 case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
89 case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
90 return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
91 case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
92 return CVMX_ADD_IO_SEG(0x0001180000003820ull) + (offset) * 128;
93 }
94 return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
95}
96
97static inline uint64_t CVMX_SMIX_RD_DAT(unsigned long offset)
98{
99 switch (cvmx_get_octeon_family()) {
100 case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
101 case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
102 case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
103 case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
104 case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
105 return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
106 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
107 case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
108 case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
109 case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
110 case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
111 case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
112 return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
113 case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
114 return CVMX_ADD_IO_SEG(0x0001180000003810ull) + (offset) * 128;
115 }
116 return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
117}
118
119static inline uint64_t CVMX_SMIX_WR_DAT(unsigned long offset)
120{
121 switch (cvmx_get_octeon_family()) {
122 case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
123 case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
124 case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
125 case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
126 case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
127 return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
128 case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
129 case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
130 case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
131 case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
132 case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
133 case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
134 return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
135 case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
136 return CVMX_ADD_IO_SEG(0x0001180000003808ull) + (offset) * 128;
137 }
138 return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
139}
140
141union cvmx_smix_clk {
142 uint64_t u64;
143 struct cvmx_smix_clk_s {
144#ifdef __BIG_ENDIAN_BITFIELD
145 uint64_t reserved_25_63:39;
146 uint64_t mode:1;
147 uint64_t reserved_21_23:3;
148 uint64_t sample_hi:5;
149 uint64_t sample_mode:1;
150 uint64_t reserved_14_14:1;
151 uint64_t clk_idle:1;
152 uint64_t preamble:1;
153 uint64_t sample:4;
154 uint64_t phase:8;
155#else
156 uint64_t phase:8;
157 uint64_t sample:4;
158 uint64_t preamble:1;
159 uint64_t clk_idle:1;
160 uint64_t reserved_14_14:1;
161 uint64_t sample_mode:1;
162 uint64_t sample_hi:5;
163 uint64_t reserved_21_23:3;
164 uint64_t mode:1;
165 uint64_t reserved_25_63:39;
166#endif
167 } s;
168 struct cvmx_smix_clk_cn30xx {
169#ifdef __BIG_ENDIAN_BITFIELD
170 uint64_t reserved_21_63:43;
171 uint64_t sample_hi:5;
172 uint64_t sample_mode:1;
173 uint64_t reserved_14_14:1;
174 uint64_t clk_idle:1;
175 uint64_t preamble:1;
176 uint64_t sample:4;
177 uint64_t phase:8;
178#else
179 uint64_t phase:8;
180 uint64_t sample:4;
181 uint64_t preamble:1;
182 uint64_t clk_idle:1;
183 uint64_t reserved_14_14:1;
184 uint64_t sample_mode:1;
185 uint64_t sample_hi:5;
186 uint64_t reserved_21_63:43;
187#endif
188 } cn30xx;
189};
190
191union cvmx_smix_cmd {
192 uint64_t u64;
193 struct cvmx_smix_cmd_s {
194#ifdef __BIG_ENDIAN_BITFIELD
195 uint64_t reserved_18_63:46;
196 uint64_t phy_op:2;
197 uint64_t reserved_13_15:3;
198 uint64_t phy_adr:5;
199 uint64_t reserved_5_7:3;
200 uint64_t reg_adr:5;
201#else
202 uint64_t reg_adr:5;
203 uint64_t reserved_5_7:3;
204 uint64_t phy_adr:5;
205 uint64_t reserved_13_15:3;
206 uint64_t phy_op:2;
207 uint64_t reserved_18_63:46;
208#endif
209 } s;
210 struct cvmx_smix_cmd_cn30xx {
211#ifdef __BIG_ENDIAN_BITFIELD
212 uint64_t reserved_17_63:47;
213 uint64_t phy_op:1;
214 uint64_t reserved_13_15:3;
215 uint64_t phy_adr:5;
216 uint64_t reserved_5_7:3;
217 uint64_t reg_adr:5;
218#else
219 uint64_t reg_adr:5;
220 uint64_t reserved_5_7:3;
221 uint64_t phy_adr:5;
222 uint64_t reserved_13_15:3;
223 uint64_t phy_op:1;
224 uint64_t reserved_17_63:47;
225#endif
226 } cn30xx;
227};
228
229union cvmx_smix_en {
230 uint64_t u64;
231 struct cvmx_smix_en_s {
232#ifdef __BIG_ENDIAN_BITFIELD
233 uint64_t reserved_1_63:63;
234 uint64_t en:1;
235#else
236 uint64_t en:1;
237 uint64_t reserved_1_63:63;
238#endif
239 } s;
240};
241
242union cvmx_smix_rd_dat {
243 uint64_t u64;
244 struct cvmx_smix_rd_dat_s {
245#ifdef __BIG_ENDIAN_BITFIELD
246 uint64_t reserved_18_63:46;
247 uint64_t pending:1;
248 uint64_t val:1;
249 uint64_t dat:16;
250#else
251 uint64_t dat:16;
252 uint64_t val:1;
253 uint64_t pending:1;
254 uint64_t reserved_18_63:46;
255#endif
256 } s;
257};
258
259union cvmx_smix_wr_dat {
260 uint64_t u64;
261 struct cvmx_smix_wr_dat_s {
262#ifdef __BIG_ENDIAN_BITFIELD
263 uint64_t reserved_18_63:46;
264 uint64_t pending:1;
265 uint64_t val:1;
266 uint64_t dat:16;
267#else
268 uint64_t dat:16;
269 uint64_t val:1;
270 uint64_t pending:1;
271 uint64_t reserved_18_63:46;
272#endif
273 } s;
274};
275
276#endif
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h
index 3206245d1ed6..23574c27eb40 100644
--- a/arch/mips/include/asm/pci/bridge.h
+++ b/arch/mips/include/asm/pci/bridge.h
@@ -45,18 +45,21 @@
45 45
46#ifndef __ASSEMBLY__ 46#ifndef __ASSEMBLY__
47 47
48/* 48#define ATE_V 0x01
49 * All accesses to bridge hardware registers must be done 49#define ATE_CO 0x02
50 * using 32-bit loads and stores. 50#define ATE_PREC 0x04
51 */ 51#define ATE_PREF 0x08
52typedef u32 bridgereg_t; 52#define ATE_BAR 0x10
53
54#define ATE_PFNSHIFT 12
55#define ATE_TIDSHIFT 8
56#define ATE_RMFSHIFT 48
53 57
54typedef u64 bridge_ate_t; 58#define mkate(xaddr, xid, attr) (((xaddr) & 0x0000fffffffff000ULL) | \
59 ((xid)<<ATE_TIDSHIFT) | \
60 (attr))
55 61
56/* pointers to bridge ATEs 62#define BRIDGE_INTERNAL_ATES 128
57 * are always "pointer to volatile"
58 */
59typedef volatile bridge_ate_t *bridge_ate_p;
60 63
61/* 64/*
62 * It is generally preferred that hardware registers on the bridge 65 * It is generally preferred that hardware registers on the bridge
@@ -65,7 +68,7 @@ typedef volatile bridge_ate_t *bridge_ate_p;
65 * Generated from Bridge spec dated 04oct95 68 * Generated from Bridge spec dated 04oct95
66 */ 69 */
67 70
68typedef volatile struct bridge_s { 71struct bridge_regs {
69 /* Local Registers 0x000000-0x00FFFF */ 72 /* Local Registers 0x000000-0x00FFFF */
70 73
71 /* standard widget configuration 0x000000-0x000057 */ 74 /* standard widget configuration 0x000000-0x000057 */
@@ -86,105 +89,105 @@ typedef volatile struct bridge_s {
86#define b_wid_tflush b_widget.w_tflush 89#define b_wid_tflush b_widget.w_tflush
87 90
88 /* bridge-specific widget configuration 0x000058-0x00007F */ 91 /* bridge-specific widget configuration 0x000058-0x00007F */
89 bridgereg_t _pad_000058; 92 u32 _pad_000058;
90 bridgereg_t b_wid_aux_err; /* 0x00005C */ 93 u32 b_wid_aux_err; /* 0x00005C */
91 bridgereg_t _pad_000060; 94 u32 _pad_000060;
92 bridgereg_t b_wid_resp_upper; /* 0x000064 */ 95 u32 b_wid_resp_upper; /* 0x000064 */
93 bridgereg_t _pad_000068; 96 u32 _pad_000068;
94 bridgereg_t b_wid_resp_lower; /* 0x00006C */ 97 u32 b_wid_resp_lower; /* 0x00006C */
95 bridgereg_t _pad_000070; 98 u32 _pad_000070;
96 bridgereg_t b_wid_tst_pin_ctrl; /* 0x000074 */ 99 u32 b_wid_tst_pin_ctrl; /* 0x000074 */
97 bridgereg_t _pad_000078[2]; 100 u32 _pad_000078[2];
98 101
99 /* PMU & Map 0x000080-0x00008F */ 102 /* PMU & Map 0x000080-0x00008F */
100 bridgereg_t _pad_000080; 103 u32 _pad_000080;
101 bridgereg_t b_dir_map; /* 0x000084 */ 104 u32 b_dir_map; /* 0x000084 */
102 bridgereg_t _pad_000088[2]; 105 u32 _pad_000088[2];
103 106
104 /* SSRAM 0x000090-0x00009F */ 107 /* SSRAM 0x000090-0x00009F */
105 bridgereg_t _pad_000090; 108 u32 _pad_000090;
106 bridgereg_t b_ram_perr; /* 0x000094 */ 109 u32 b_ram_perr; /* 0x000094 */
107 bridgereg_t _pad_000098[2]; 110 u32 _pad_000098[2];
108 111
109 /* Arbitration 0x0000A0-0x0000AF */ 112 /* Arbitration 0x0000A0-0x0000AF */
110 bridgereg_t _pad_0000A0; 113 u32 _pad_0000A0;
111 bridgereg_t b_arb; /* 0x0000A4 */ 114 u32 b_arb; /* 0x0000A4 */
112 bridgereg_t _pad_0000A8[2]; 115 u32 _pad_0000A8[2];
113 116
114 /* Number In A Can 0x0000B0-0x0000BF */ 117 /* Number In A Can 0x0000B0-0x0000BF */
115 bridgereg_t _pad_0000B0; 118 u32 _pad_0000B0;
116 bridgereg_t b_nic; /* 0x0000B4 */ 119 u32 b_nic; /* 0x0000B4 */
117 bridgereg_t _pad_0000B8[2]; 120 u32 _pad_0000B8[2];
118 121
119 /* PCI/GIO 0x0000C0-0x0000FF */ 122 /* PCI/GIO 0x0000C0-0x0000FF */
120 bridgereg_t _pad_0000C0; 123 u32 _pad_0000C0;
121 bridgereg_t b_bus_timeout; /* 0x0000C4 */ 124 u32 b_bus_timeout; /* 0x0000C4 */
122#define b_pci_bus_timeout b_bus_timeout 125#define b_pci_bus_timeout b_bus_timeout
123 126
124 bridgereg_t _pad_0000C8; 127 u32 _pad_0000C8;
125 bridgereg_t b_pci_cfg; /* 0x0000CC */ 128 u32 b_pci_cfg; /* 0x0000CC */
126 bridgereg_t _pad_0000D0; 129 u32 _pad_0000D0;
127 bridgereg_t b_pci_err_upper; /* 0x0000D4 */ 130 u32 b_pci_err_upper; /* 0x0000D4 */
128 bridgereg_t _pad_0000D8; 131 u32 _pad_0000D8;
129 bridgereg_t b_pci_err_lower; /* 0x0000DC */ 132 u32 b_pci_err_lower; /* 0x0000DC */
130 bridgereg_t _pad_0000E0[8]; 133 u32 _pad_0000E0[8];
131#define b_gio_err_lower b_pci_err_lower 134#define b_gio_err_lower b_pci_err_lower
132#define b_gio_err_upper b_pci_err_upper 135#define b_gio_err_upper b_pci_err_upper
133 136
134 /* Interrupt 0x000100-0x0001FF */ 137 /* Interrupt 0x000100-0x0001FF */
135 bridgereg_t _pad_000100; 138 u32 _pad_000100;
136 bridgereg_t b_int_status; /* 0x000104 */ 139 u32 b_int_status; /* 0x000104 */
137 bridgereg_t _pad_000108; 140 u32 _pad_000108;
138 bridgereg_t b_int_enable; /* 0x00010C */ 141 u32 b_int_enable; /* 0x00010C */
139 bridgereg_t _pad_000110; 142 u32 _pad_000110;
140 bridgereg_t b_int_rst_stat; /* 0x000114 */ 143 u32 b_int_rst_stat; /* 0x000114 */
141 bridgereg_t _pad_000118; 144 u32 _pad_000118;
142 bridgereg_t b_int_mode; /* 0x00011C */ 145 u32 b_int_mode; /* 0x00011C */
143 bridgereg_t _pad_000120; 146 u32 _pad_000120;
144 bridgereg_t b_int_device; /* 0x000124 */ 147 u32 b_int_device; /* 0x000124 */
145 bridgereg_t _pad_000128; 148 u32 _pad_000128;
146 bridgereg_t b_int_host_err; /* 0x00012C */ 149 u32 b_int_host_err; /* 0x00012C */
147 150
148 struct { 151 struct {
149 bridgereg_t __pad; /* 0x0001{30,,,68} */ 152 u32 __pad; /* 0x0001{30,,,68} */
150 bridgereg_t addr; /* 0x0001{34,,,6C} */ 153 u32 addr; /* 0x0001{34,,,6C} */
151 } b_int_addr[8]; /* 0x000130 */ 154 } b_int_addr[8]; /* 0x000130 */
152 155
153 bridgereg_t _pad_000170[36]; 156 u32 _pad_000170[36];
154 157
155 /* Device 0x000200-0x0003FF */ 158 /* Device 0x000200-0x0003FF */
156 struct { 159 struct {
157 bridgereg_t __pad; /* 0x0002{00,,,38} */ 160 u32 __pad; /* 0x0002{00,,,38} */
158 bridgereg_t reg; /* 0x0002{04,,,3C} */ 161 u32 reg; /* 0x0002{04,,,3C} */
159 } b_device[8]; /* 0x000200 */ 162 } b_device[8]; /* 0x000200 */
160 163
161 struct { 164 struct {
162 bridgereg_t __pad; /* 0x0002{40,,,78} */ 165 u32 __pad; /* 0x0002{40,,,78} */
163 bridgereg_t reg; /* 0x0002{44,,,7C} */ 166 u32 reg; /* 0x0002{44,,,7C} */
164 } b_wr_req_buf[8]; /* 0x000240 */ 167 } b_wr_req_buf[8]; /* 0x000240 */
165 168
166 struct { 169 struct {
167 bridgereg_t __pad; /* 0x0002{80,,,88} */ 170 u32 __pad; /* 0x0002{80,,,88} */
168 bridgereg_t reg; /* 0x0002{84,,,8C} */ 171 u32 reg; /* 0x0002{84,,,8C} */
169 } b_rrb_map[2]; /* 0x000280 */ 172 } b_rrb_map[2]; /* 0x000280 */
170#define b_even_resp b_rrb_map[0].reg /* 0x000284 */ 173#define b_even_resp b_rrb_map[0].reg /* 0x000284 */
171#define b_odd_resp b_rrb_map[1].reg /* 0x00028C */ 174#define b_odd_resp b_rrb_map[1].reg /* 0x00028C */
172 175
173 bridgereg_t _pad_000290; 176 u32 _pad_000290;
174 bridgereg_t b_resp_status; /* 0x000294 */ 177 u32 b_resp_status; /* 0x000294 */
175 bridgereg_t _pad_000298; 178 u32 _pad_000298;
176 bridgereg_t b_resp_clear; /* 0x00029C */ 179 u32 b_resp_clear; /* 0x00029C */
177 180
178 bridgereg_t _pad_0002A0[24]; 181 u32 _pad_0002A0[24];
179 182
180 char _pad_000300[0x10000 - 0x000300]; 183 char _pad_000300[0x10000 - 0x000300];
181 184
182 /* Internal Address Translation Entry RAM 0x010000-0x0103FF */ 185 /* Internal Address Translation Entry RAM 0x010000-0x0103FF */
183 union { 186 union {
184 bridge_ate_t wr; /* write-only */ 187 u64 wr; /* write-only */
185 struct { 188 struct {
186 bridgereg_t _p_pad; 189 u32 _p_pad;
187 bridgereg_t rd; /* read-only */ 190 u32 rd; /* read-only */
188 } hi; 191 } hi;
189 } b_int_ate_ram[128]; 192 } b_int_ate_ram[128];
190 193
@@ -192,8 +195,8 @@ typedef volatile struct bridge_s {
192 195
193 /* Internal Address Translation Entry RAM LOW 0x011000-0x0113FF */ 196 /* Internal Address Translation Entry RAM LOW 0x011000-0x0113FF */
194 struct { 197 struct {
195 bridgereg_t _p_pad; 198 u32 _p_pad;
196 bridgereg_t rd; /* read-only */ 199 u32 rd; /* read-only */
197 } b_int_ate_ram_lo[128]; 200 } b_int_ate_ram_lo[128];
198 201
199 char _pad_011400[0x20000 - 0x011400]; 202 char _pad_011400[0x20000 - 0x011400];
@@ -212,7 +215,7 @@ typedef volatile struct bridge_s {
212 } f[8]; 215 } f[8];
213 } b_type0_cfg_dev[8]; /* 0x020000 */ 216 } b_type0_cfg_dev[8]; /* 0x020000 */
214 217
215 /* PCI Type 1 Configuration Space 0x028000-0x028FFF */ 218 /* PCI Type 1 Configuration Space 0x028000-0x028FFF */
216 union { /* make all access sizes available. */ 219 union { /* make all access sizes available. */
217 u8 c[0x1000 / 1]; 220 u8 c[0x1000 / 1];
218 u16 s[0x1000 / 2]; 221 u16 s[0x1000 / 2];
@@ -233,7 +236,7 @@ typedef volatile struct bridge_s {
233 u8 _pad_030007[0x04fff8]; /* 0x030008-0x07FFFF */ 236 u8 _pad_030007[0x04fff8]; /* 0x030008-0x07FFFF */
234 237
235 /* External Address Translation Entry RAM 0x080000-0x0FFFFF */ 238 /* External Address Translation Entry RAM 0x080000-0x0FFFFF */
236 bridge_ate_t b_ext_ate_ram[0x10000]; 239 u64 b_ext_ate_ram[0x10000];
237 240
238 /* Reserved 0x100000-0x1FFFFF */ 241 /* Reserved 0x100000-0x1FFFFF */
239 char _pad_100000[0x200000-0x100000]; 242 char _pad_100000[0x200000-0x100000];
@@ -259,13 +262,13 @@ typedef volatile struct bridge_s {
259 u32 l[0x400000 / 4]; /* read-only */ 262 u32 l[0x400000 / 4]; /* read-only */
260 u64 d[0x400000 / 8]; /* read-only */ 263 u64 d[0x400000 / 8]; /* read-only */
261 } b_external_flash; /* 0xC00000 */ 264 } b_external_flash; /* 0xC00000 */
262} bridge_t; 265};
263 266
264/* 267/*
265 * Field formats for Error Command Word and Auxiliary Error Command Word 268 * Field formats for Error Command Word and Auxiliary Error Command Word
266 * of bridge. 269 * of bridge.
267 */ 270 */
268typedef struct bridge_err_cmdword_s { 271struct bridge_err_cmdword {
269 union { 272 union {
270 u32 cmd_word; 273 u32 cmd_word;
271 struct { 274 struct {
@@ -282,7 +285,7 @@ typedef struct bridge_err_cmdword_s {
282 rsvd:8; 285 rsvd:8;
283 } berr_st; 286 } berr_st;
284 } berr_un; 287 } berr_un;
285} bridge_err_cmdword_t; 288};
286 289
287#define berr_field berr_un.berr_st 290#define berr_field berr_un.berr_st
288#endif /* !__ASSEMBLY__ */ 291#endif /* !__ASSEMBLY__ */
@@ -290,7 +293,7 @@ typedef struct bridge_err_cmdword_s {
290/* 293/*
291 * The values of these macros can and should be crosschecked 294 * The values of these macros can and should be crosschecked
292 * regularly against the offsets of the like-named fields 295 * regularly against the offsets of the like-named fields
293 * within the "bridge_t" structure above. 296 * within the bridge_regs structure above.
294 */ 297 */
295 298
296/* Byte offset macros for Bridge internal registers */ 299/* Byte offset macros for Bridge internal registers */
@@ -797,49 +800,14 @@ typedef struct bridge_err_cmdword_s {
797#define PCI64_ATTR_RMF_MASK 0x00ff000000000000 800#define PCI64_ATTR_RMF_MASK 0x00ff000000000000
798#define PCI64_ATTR_RMF_SHFT 48 801#define PCI64_ATTR_RMF_SHFT 48
799 802
800#ifndef __ASSEMBLY__
801/* Address translation entry for mapped pci32 accesses */
802typedef union ate_u {
803 u64 ent;
804 struct ate_s {
805 u64 rmf:16;
806 u64 addr:36;
807 u64 targ:4;
808 u64 reserved:3;
809 u64 barrier:1;
810 u64 prefetch:1;
811 u64 precise:1;
812 u64 coherent:1;
813 u64 valid:1;
814 } field;
815} ate_t;
816#endif /* !__ASSEMBLY__ */
817
818#define ATE_V 0x01
819#define ATE_CO 0x02
820#define ATE_PREC 0x04
821#define ATE_PREF 0x08
822#define ATE_BAR 0x10
823
824#define ATE_PFNSHIFT 12
825#define ATE_TIDSHIFT 8
826#define ATE_RMFSHIFT 48
827
828#define mkate(xaddr, xid, attr) ((xaddr) & 0x0000fffffffff000ULL) | \
829 ((xid)<<ATE_TIDSHIFT) | \
830 (attr)
831
832#define BRIDGE_INTERNAL_ATES 128
833
834struct bridge_controller { 803struct bridge_controller {
835 struct pci_controller pc; 804 struct pci_controller pc;
836 struct resource mem; 805 struct resource mem;
837 struct resource io; 806 struct resource io;
838 struct resource busn; 807 struct resource busn;
839 bridge_t *base; 808 struct bridge_regs *base;
840 nasid_t nasid; 809 nasid_t nasid;
841 unsigned int widget_id; 810 unsigned int widget_id;
842 unsigned int irq_cpu;
843 u64 baddr; 811 u64 baddr;
844 unsigned int pci_int[8]; 812 unsigned int pci_int[8];
845}; 813};
@@ -847,8 +815,14 @@ struct bridge_controller {
847#define BRIDGE_CONTROLLER(bus) \ 815#define BRIDGE_CONTROLLER(bus) \
848 ((struct bridge_controller *)((bus)->sysdata)) 816 ((struct bridge_controller *)((bus)->sysdata))
849 817
850extern void register_bridge_irq(unsigned int irq); 818#define bridge_read(bc, reg) __raw_readl(&bc->base->reg)
851extern int request_bridge_irq(struct bridge_controller *bc); 819#define bridge_write(bc, reg, val) __raw_writel(val, &bc->base->reg)
820#define bridge_set(bc, reg, val) \
821 __raw_writel(__raw_readl(&bc->base->reg) | (val), &bc->base->reg)
822#define bridge_clr(bc, reg, val) \
823 __raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg)
824
825extern int request_bridge_irq(struct bridge_controller *bc, int pin);
852 826
853extern struct pci_ops bridge_pci_ops; 827extern struct pci_ops bridge_pci_ops;
854 828
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 910851c62db3..4ccb465ef3f2 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -17,6 +17,7 @@
17#include <asm/pgtable-64.h> 17#include <asm/pgtable-64.h>
18#endif 18#endif
19 19
20#include <asm/cmpxchg.h>
20#include <asm/io.h> 21#include <asm/io.h>
21#include <asm/pgtable-bits.h> 22#include <asm/pgtable-bits.h>
22 23
@@ -204,51 +205,11 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
204 * Make sure the buddy is global too (if it's !none, 205 * Make sure the buddy is global too (if it's !none,
205 * it better already be global) 206 * it better already be global)
206 */ 207 */
207#ifdef CONFIG_SMP 208# if defined(CONFIG_PHYS_ADDR_T_64BIT) && !defined(CONFIG_CPU_MIPS32)
208 /* 209 cmpxchg64(&buddy->pte, 0, _PAGE_GLOBAL);
209 * For SMP, multiple CPUs can race, so we need to do 210# else
210 * this atomically. 211 cmpxchg(&buddy->pte, 0, _PAGE_GLOBAL);
211 */ 212# endif
212 unsigned long page_global = _PAGE_GLOBAL;
213 unsigned long tmp;
214
215 if (kernel_uses_llsc && R10000_LLSC_WAR) {
216 __asm__ __volatile__ (
217 " .set push \n"
218 " .set arch=r4000 \n"
219 " .set noreorder \n"
220 "1:" __LL "%[tmp], %[buddy] \n"
221 " bnez %[tmp], 2f \n"
222 " or %[tmp], %[tmp], %[global] \n"
223 __SC "%[tmp], %[buddy] \n"
224 " beqzl %[tmp], 1b \n"
225 " nop \n"
226 "2: \n"
227 " .set pop \n"
228 : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
229 : [global] "r" (page_global));
230 } else if (kernel_uses_llsc) {
231 loongson_llsc_mb();
232 __asm__ __volatile__ (
233 " .set push \n"
234 " .set "MIPS_ISA_ARCH_LEVEL" \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 : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
245 : [global] "r" (page_global));
246 loongson_llsc_mb();
247 }
248#else /* !CONFIG_SMP */
249 if (pte_none(*buddy))
250 pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
251#endif /* CONFIG_SMP */
252 } 213 }
253#endif 214#endif
254} 215}
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
index b7123f9c0785..65618ff1280c 100644
--- a/arch/mips/include/asm/smp-ops.h
+++ b/arch/mips/include/asm/smp-ops.h
@@ -29,6 +29,7 @@ struct plat_smp_ops {
29 int (*boot_secondary)(int cpu, struct task_struct *idle); 29 int (*boot_secondary)(int cpu, struct task_struct *idle);
30 void (*smp_setup)(void); 30 void (*smp_setup)(void);
31 void (*prepare_cpus)(unsigned int max_cpus); 31 void (*prepare_cpus)(unsigned int max_cpus);
32 void (*prepare_boot_cpu)(void);
32#ifdef CONFIG_HOTPLUG_CPU 33#ifdef CONFIG_HOTPLUG_CPU
33 int (*cpu_disable)(void); 34 int (*cpu_disable)(void);
34 void (*cpu_die)(unsigned int cpu); 35 void (*cpu_die)(unsigned int cpu);
diff --git a/arch/mips/include/asm/sn/addrs.h b/arch/mips/include/asm/sn/addrs.h
index 66814f8ba8e8..837d23e24976 100644
--- a/arch/mips/include/asm/sn/addrs.h
+++ b/arch/mips/include/asm/sn/addrs.h
@@ -27,16 +27,11 @@
27 27
28#ifndef __ASSEMBLY__ 28#ifndef __ASSEMBLY__
29 29
30#define PS_UINT_CAST (unsigned long)
31#define UINT64_CAST (unsigned long) 30#define UINT64_CAST (unsigned long)
32 31
33#define HUBREG_CAST (volatile hubreg_t *)
34
35#else /* __ASSEMBLY__ */ 32#else /* __ASSEMBLY__ */
36 33
37#define PS_UINT_CAST
38#define UINT64_CAST 34#define UINT64_CAST
39#define HUBREG_CAST
40 35
41#endif /* __ASSEMBLY__ */ 36#endif /* __ASSEMBLY__ */
42 37
@@ -256,42 +251,23 @@
256 * Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S(). 251 * Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
257 * They're always safe. 252 * They're always safe.
258 */ 253 */
259#define LOCAL_HUB_ADDR(_x) (HUBREG_CAST (IALIAS_BASE + (_x))) 254#define LOCAL_HUB_ADDR(_x) (IALIAS_BASE + (_x))
260#define REMOTE_HUB_ADDR(_n, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \ 255#define REMOTE_HUB_ADDR(_n, _x) ((NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x)))
261 0x800000 + (_x)))
262#ifdef CONFIG_SGI_IP27
263#define REMOTE_HUB_PI_ADDR(_n, _sn, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \
264 0x800000 + (_x)))
265#endif /* CONFIG_SGI_IP27 */
266 256
267#ifndef __ASSEMBLY__ 257#ifndef __ASSEMBLY__
268 258
269#define HUB_L(_a) *(_a) 259#define LOCAL_HUB_PTR(_x) ((u64 *)LOCAL_HUB_ADDR((_x)))
270#define HUB_S(_a, _d) *(_a) = (_d) 260#define REMOTE_HUB_PTR(_n, _x) ((u64 *)REMOTE_HUB_ADDR((_n), (_x)))
271 261
272#define LOCAL_HUB_L(_r) HUB_L(LOCAL_HUB_ADDR(_r)) 262#define LOCAL_HUB_L(_r) __raw_readq(LOCAL_HUB_PTR(_r))
273#define LOCAL_HUB_S(_r, _d) HUB_S(LOCAL_HUB_ADDR(_r), (_d)) 263#define LOCAL_HUB_S(_r, _d) __raw_writeq((_d), LOCAL_HUB_PTR(_r))
274#define REMOTE_HUB_L(_n, _r) HUB_L(REMOTE_HUB_ADDR((_n), (_r))) 264#define REMOTE_HUB_L(_n, _r) __raw_readq(REMOTE_HUB_PTR((_n), (_r)))
275#define REMOTE_HUB_S(_n, _r, _d) HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d)) 265#define REMOTE_HUB_S(_n, _r, _d) __raw_writeq((_d), \
276#define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r))) 266 REMOTE_HUB_PTR((_n), (_r)))
277#define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
278 267
279#endif /* !__ASSEMBLY__ */ 268#endif /* !__ASSEMBLY__ */
280 269
281/* 270/*
282 * The following macros are used to get to a hub/bridge register, given
283 * the base of the register space.
284 */
285#define HUB_REG_PTR(_base, _off) \
286 (HUBREG_CAST((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
287
288#define HUB_REG_PTR_L(_base, _off) \
289 HUB_L(HUB_REG_PTR((_base), (_off)))
290
291#define HUB_REG_PTR_S(_base, _off, _data) \
292 HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
293
294/*
295 * Software structure locations -- permanently fixed 271 * Software structure locations -- permanently fixed
296 * See diagram in kldir.h 272 * See diagram in kldir.h
297 */ 273 */
@@ -387,44 +363,14 @@
387 363
388#define SYMMON_STK_END(nasid) (SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size) 364#define SYMMON_STK_END(nasid) (SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size)
389 365
390/* loading symmon 4k below UNIX. the arcs loader needs the topaddr for a
391 * relocatable program
392 */
393#define UNIX_DEBUG_LOADADDR 0x300000
394#define SYMMON_LOADADDR(nasid) \
395 TO_NODE(nasid, PHYS_TO_K0(UNIX_DEBUG_LOADADDR - 0x1000))
396
397#define FREEMEM_OFFSET(nasid) KLD_FREEMEM(nasid)->offset
398#define FREEMEM_ADDR(nasid) SYMMON_STK_END(nasid)
399/*
400 * XXX
401 * Fix this. FREEMEM_ADDR should be aware of if symmon is loaded.
402 * Also, it should take into account what prom thinks to be a safe
403 * address
404 PHYS_TO_K0(NODE_OFFSET(nasid) + FREEMEM_OFFSET(nasid))
405 */
406#define FREEMEM_SIZE(nasid) KLD_FREEMEM(nasid)->size
407
408#define PI_ERROR_OFFSET(nasid) KLD_PI_ERROR(nasid)->offset
409#define PI_ERROR_ADDR(nasid) \
410 TO_NODE_UNCAC((nasid), PI_ERROR_OFFSET(nasid))
411#define PI_ERROR_SIZE(nasid) KLD_PI_ERROR(nasid)->size
412
413#define NODE_OFFSET_TO_K0(_nasid, _off) \ 366#define NODE_OFFSET_TO_K0(_nasid, _off) \
414 PHYS_TO_K0((NODE_OFFSET(_nasid) + (_off)) | CAC_BASE) 367 PHYS_TO_K0((NODE_OFFSET(_nasid) + (_off)) | CAC_BASE)
415#define NODE_OFFSET_TO_K1(_nasid, _off) \ 368#define NODE_OFFSET_TO_K1(_nasid, _off) \
416 TO_UNCAC((NODE_OFFSET(_nasid) + (_off)) | UNCAC_BASE) 369 TO_UNCAC((NODE_OFFSET(_nasid) + (_off)) | UNCAC_BASE)
417#define K0_TO_NODE_OFFSET(_k0addr) \
418 ((__psunsigned_t)(_k0addr) & NODE_ADDRSPACE_MASK)
419 370
420#define KERN_VARS_ADDR(nasid) KLD_KERN_VARS(nasid)->pointer 371#define KERN_VARS_ADDR(nasid) KLD_KERN_VARS(nasid)->pointer
421#define KERN_VARS_SIZE(nasid) KLD_KERN_VARS(nasid)->size 372#define KERN_VARS_SIZE(nasid) KLD_KERN_VARS(nasid)->size
422 373
423#define KERN_XP_ADDR(nasid) KLD_KERN_XP(nasid)->pointer
424#define KERN_XP_SIZE(nasid) KLD_KERN_XP(nasid)->size
425
426#define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET)
427
428#endif /* !__ASSEMBLY__ */ 374#endif /* !__ASSEMBLY__ */
429 375
430 376
diff --git a/arch/mips/include/asm/sn/arch.h b/arch/mips/include/asm/sn/arch.h
index 471e6870d876..3f1fb1454749 100644
--- a/arch/mips/include/asm/sn/arch.h
+++ b/arch/mips/include/asm/sn/arch.h
@@ -17,8 +17,6 @@
17#include <asm/sn/sn0/arch.h> 17#include <asm/sn/sn0/arch.h>
18#endif 18#endif
19 19
20typedef u64 hubreg_t;
21
22#define cputonasid(cpu) (sn_cpu_info[(cpu)].p_nasid) 20#define cputonasid(cpu) (sn_cpu_info[(cpu)].p_nasid)
23#define cputoslice(cpu) (sn_cpu_info[(cpu)].p_slice) 21#define cputoslice(cpu) (sn_cpu_info[(cpu)].p_slice)
24#define makespnum(_nasid, _slice) \ 22#define makespnum(_nasid, _slice) \
diff --git a/arch/mips/include/asm/sn/io.h b/arch/mips/include/asm/sn/io.h
index d5174d04538c..211f1e83b523 100644
--- a/arch/mips/include/asm/sn/io.h
+++ b/arch/mips/include/asm/sn/io.h
@@ -44,7 +44,7 @@
44 IIO_ITTE_PUT((nasid), HUB_PIO_MAP_TO_MEM, \ 44 IIO_ITTE_PUT((nasid), HUB_PIO_MAP_TO_MEM, \
45 (bigwin), IIO_ITTE_INVALID_WIDGET, 0) 45 (bigwin), IIO_ITTE_INVALID_WIDGET, 0)
46 46
47#define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin)) 47#define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_PTR((nasid), IIO_ITTE(bigwin))
48 48
49/* 49/*
50 * Macro which takes the widget number, and returns the 50 * Macro which takes the widget number, and returns the
diff --git a/arch/mips/include/asm/sn/sn0/addrs.h b/arch/mips/include/asm/sn/sn0/addrs.h
index 6b53070f400f..f13df84edfdd 100644
--- a/arch/mips/include/asm/sn/sn0/addrs.h
+++ b/arch/mips/include/asm/sn/sn0/addrs.h
@@ -134,11 +134,6 @@
134 134
135#define CALIAS_BASE CAC_BASE 135#define CALIAS_BASE CAC_BASE
136 136
137
138
139#define BRIDGE_REG_PTR(_base, _off) ((volatile bridgereg_t *) \
140 ((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
141
142#define SN0_WIDGET_BASE(_nasid, _wid) (NODE_SWIN_BASE((_nasid), (_wid))) 137#define SN0_WIDGET_BASE(_nasid, _wid) (NODE_SWIN_BASE((_nasid), (_wid)))
143 138
144/* Turn on sable logging for the processors whose bits are set. */ 139/* Turn on sable logging for the processors whose bits are set. */
diff --git a/arch/mips/include/asm/tlbflush.h b/arch/mips/include/asm/tlbflush.h
index 40a361092491..9789e7a32def 100644
--- a/arch/mips/include/asm/tlbflush.h
+++ b/arch/mips/include/asm/tlbflush.h
@@ -14,7 +14,6 @@
14 * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages 14 * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
15 */ 15 */
16extern void local_flush_tlb_all(void); 16extern void local_flush_tlb_all(void);
17extern void local_flush_tlb_mm(struct mm_struct *mm);
18extern void local_flush_tlb_range(struct vm_area_struct *vma, 17extern void local_flush_tlb_range(struct vm_area_struct *vma,
19 unsigned long start, unsigned long end); 18 unsigned long start, unsigned long end);
20extern void local_flush_tlb_kernel_range(unsigned long start, 19extern void local_flush_tlb_kernel_range(unsigned long start,
@@ -23,6 +22,8 @@ extern void local_flush_tlb_page(struct vm_area_struct *vma,
23 unsigned long page); 22 unsigned long page);
24extern void local_flush_tlb_one(unsigned long vaddr); 23extern void local_flush_tlb_one(unsigned long vaddr);
25 24
25#include <asm/mmu_context.h>
26
26#ifdef CONFIG_SMP 27#ifdef CONFIG_SMP
27 28
28extern void flush_tlb_all(void); 29extern void flush_tlb_all(void);
@@ -36,7 +37,7 @@ extern void flush_tlb_one(unsigned long vaddr);
36#else /* CONFIG_SMP */ 37#else /* CONFIG_SMP */
37 38
38#define flush_tlb_all() local_flush_tlb_all() 39#define flush_tlb_all() local_flush_tlb_all()
39#define flush_tlb_mm(mm) local_flush_tlb_mm(mm) 40#define flush_tlb_mm(mm) drop_mmu_context(mm)
40#define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, end) 41#define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, end)
41#define flush_tlb_kernel_range(vmaddr,end) \ 42#define flush_tlb_kernel_range(vmaddr,end) \
42 local_flush_tlb_kernel_range(vmaddr, end) 43 local_flush_tlb_kernel_range(vmaddr, end)
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index afb40f8bce96..7e63c54eb8d2 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -31,7 +31,6 @@
31 31
32#define JZ4740_EMC_SDRAM_CTRL 0x80 32#define JZ4740_EMC_SDRAM_CTRL 0x80
33 33
34
35static void __init jz4740_detect_mem(void) 34static void __init jz4740_detect_mem(void)
36{ 35{
37 void __iomem *jz_emc_base; 36 void __iomem *jz_emc_base;
@@ -66,15 +65,22 @@ static unsigned long __init get_board_mach_type(const void *fdt)
66void __init plat_mem_setup(void) 65void __init plat_mem_setup(void)
67{ 66{
68 int offset; 67 int offset;
68 void *dtb;
69 69
70 jz4740_reset_init(); 70 jz4740_reset_init();
71 __dt_setup_arch(__dtb_start);
72 71
73 offset = fdt_path_offset(__dtb_start, "/memory"); 72 if (__dtb_start != __dtb_end)
73 dtb = __dtb_start;
74 else
75 dtb = (void *)fw_passed_dtb;
76
77 __dt_setup_arch(dtb);
78
79 offset = fdt_path_offset(dtb, "/memory");
74 if (offset < 0) 80 if (offset < 0)
75 jz4740_detect_mem(); 81 jz4740_detect_mem();
76 82
77 mips_machtype = get_board_mach_type(__dtb_start); 83 mips_machtype = get_board_mach_type(dtb);
78} 84}
79 85
80void __init device_tree_init(void) 86void __init device_tree_init(void)
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 95b18a194f53..d5e335e6846a 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -872,10 +872,19 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
872 872
873static inline unsigned int decode_config5(struct cpuinfo_mips *c) 873static inline unsigned int decode_config5(struct cpuinfo_mips *c)
874{ 874{
875 unsigned int config5; 875 unsigned int config5, max_mmid_width;
876 unsigned long asid_mask;
876 877
877 config5 = read_c0_config5(); 878 config5 = read_c0_config5();
878 config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE); 879 config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
880
881 if (cpu_has_mips_r6) {
882 if (!__builtin_constant_p(cpu_has_mmid) || cpu_has_mmid)
883 config5 |= MIPS_CONF5_MI;
884 else
885 config5 &= ~MIPS_CONF5_MI;
886 }
887
879 write_c0_config5(config5); 888 write_c0_config5(config5);
880 889
881 if (config5 & MIPS_CONF5_EVA) 890 if (config5 & MIPS_CONF5_EVA)
@@ -894,6 +903,50 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
894 if (config5 & MIPS_CONF5_CRCP) 903 if (config5 & MIPS_CONF5_CRCP)
895 elf_hwcap |= HWCAP_MIPS_CRC32; 904 elf_hwcap |= HWCAP_MIPS_CRC32;
896 905
906 if (cpu_has_mips_r6) {
907 /* Ensure the write to config5 above takes effect */
908 back_to_back_c0_hazard();
909
910 /* Check whether we successfully enabled MMID support */
911 config5 = read_c0_config5();
912 if (config5 & MIPS_CONF5_MI)
913 c->options |= MIPS_CPU_MMID;
914
915 /*
916 * Warn if we've hardcoded cpu_has_mmid to a value unsuitable
917 * for the CPU we're running on, or if CPUs in an SMP system
918 * have inconsistent MMID support.
919 */
920 WARN_ON(!!cpu_has_mmid != !!(config5 & MIPS_CONF5_MI));
921
922 if (cpu_has_mmid) {
923 write_c0_memorymapid(~0ul);
924 back_to_back_c0_hazard();
925 asid_mask = read_c0_memorymapid();
926
927 /*
928 * We maintain a bitmap to track MMID allocation, and
929 * need a sensible upper bound on the size of that
930 * bitmap. The initial CPU with MMID support (I6500)
931 * supports 16 bit MMIDs, which gives us an 8KiB
932 * bitmap. The architecture recommends that hardware
933 * support 32 bit MMIDs, which would give us a 512MiB
934 * bitmap - that's too big in most cases.
935 *
936 * Cap MMID width at 16 bits for now & we can revisit
937 * this if & when hardware supports anything wider.
938 */
939 max_mmid_width = 16;
940 if (asid_mask > GENMASK(max_mmid_width - 1, 0)) {
941 pr_info("Capping MMID width at %d bits",
942 max_mmid_width);
943 asid_mask = GENMASK(max_mmid_width - 1, 0);
944 }
945
946 set_cpu_asid_mask(c, asid_mask);
947 }
948 }
949
897 return config5 & MIPS_CONF_M; 950 return config5 & MIPS_CONF_M;
898} 951}
899 952
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index ba150c755fcc..85b6c60f285d 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -52,6 +52,7 @@ asmlinkage void spurious_interrupt(void)
52void __init init_IRQ(void) 52void __init init_IRQ(void)
53{ 53{
54 int i; 54 int i;
55 unsigned int order = get_order(IRQ_STACK_SIZE);
55 56
56 for (i = 0; i < NR_IRQS; i++) 57 for (i = 0; i < NR_IRQS; i++)
57 irq_set_noprobe(i); 58 irq_set_noprobe(i);
@@ -62,8 +63,7 @@ void __init init_IRQ(void)
62 arch_init_irq(); 63 arch_init_irq();
63 64
64 for_each_possible_cpu(i) { 65 for_each_possible_cpu(i) {
65 int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE; 66 void *s = (void *)__get_free_pages(GFP_KERNEL, order);
66 void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages);
67 67
68 irq_stack[i] = s; 68 irq_stack[i] = s;
69 pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, 69 pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i,
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 7f3f136572de..537e8d091874 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -382,8 +382,8 @@ void mips_cm_error_report(void)
382 sc_bit ? "True" : "False", 382 sc_bit ? "True" : "False",
383 cm2_cmd[cmd_bits], sport_bits); 383 cm2_cmd[cmd_bits], sport_bits);
384 } 384 }
385 pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error, 385 pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error,
386 cm2_causes[cause], buf); 386 cm2_causes[cause], buf);
387 pr_err("CM_ADDR =%08llx\n", cm_addr); 387 pr_err("CM_ADDR =%08llx\n", cm_addr);
388 pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]); 388 pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]);
389 } else { /* CM3 */ 389 } else { /* CM3 */
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c
index c50c89a978f1..b4d210bfcdae 100644
--- a/arch/mips/kernel/mips-r2-to-r6-emul.c
+++ b/arch/mips/kernel/mips-r2-to-r6-emul.c
@@ -2351,23 +2351,10 @@ DEFINE_SHOW_ATTRIBUTE(mipsr2_clear);
2351 2351
2352static int __init mipsr2_init_debugfs(void) 2352static int __init mipsr2_init_debugfs(void)
2353{ 2353{
2354 struct dentry *mipsr2_emul; 2354 debugfs_create_file("r2_emul_stats", S_IRUGO, mips_debugfs_dir, NULL,
2355 2355 &mipsr2_emul_fops);
2356 if (!mips_debugfs_dir) 2356 debugfs_create_file("r2_emul_stats_clear", S_IRUGO, mips_debugfs_dir,
2357 return -ENODEV; 2357 NULL, &mipsr2_clear_fops);
2358
2359 mipsr2_emul = debugfs_create_file("r2_emul_stats", S_IRUGO,
2360 mips_debugfs_dir, NULL,
2361 &mipsr2_emul_fops);
2362 if (!mipsr2_emul)
2363 return -ENOMEM;
2364
2365 mipsr2_emul = debugfs_create_file("r2_emul_stats_clear", S_IRUGO,
2366 mips_debugfs_dir, NULL,
2367 &mipsr2_clear_fops);
2368 if (!mipsr2_emul)
2369 return -ENOMEM;
2370
2371 return 0; 2358 return 0;
2372} 2359}
2373 2360
diff --git a/arch/mips/kernel/segment.c b/arch/mips/kernel/segment.c
index 2703f218202e..0a9bd7b0983b 100644
--- a/arch/mips/kernel/segment.c
+++ b/arch/mips/kernel/segment.c
@@ -95,18 +95,9 @@ static const struct file_operations segments_fops = {
95 95
96static int __init segments_info(void) 96static int __init segments_info(void)
97{ 97{
98 struct dentry *segments; 98 if (cpu_has_segments)
99 99 debugfs_create_file("segments", S_IRUGO, mips_debugfs_dir, NULL,
100 if (cpu_has_segments) { 100 &segments_fops);
101 if (!mips_debugfs_dir)
102 return -ENODEV;
103
104 segments = debugfs_create_file("segments", S_IRUGO,
105 mips_debugfs_dir, NULL,
106 &segments_fops);
107 if (!segments)
108 return -ENOMEM;
109 }
110 return 0; 101 return 0;
111} 102}
112 103
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index d2e5a5ad0e6f..5151532ad959 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -1011,12 +1011,7 @@ unsigned long fw_passed_dtb;
1011struct dentry *mips_debugfs_dir; 1011struct dentry *mips_debugfs_dir;
1012static int __init debugfs_mips(void) 1012static int __init debugfs_mips(void)
1013{ 1013{
1014 struct dentry *d; 1014 mips_debugfs_dir = debugfs_create_dir("mips", NULL);
1015
1016 d = debugfs_create_dir("mips", NULL);
1017 if (!d)
1018 return -ENOMEM;
1019 mips_debugfs_dir = d;
1020 return 0; 1015 return 0;
1021} 1016}
1022arch_initcall(debugfs_mips); 1017arch_initcall(debugfs_mips);
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index d84b9066b465..bc4bb3c6bd00 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -39,6 +39,7 @@
39 39
40#include <linux/atomic.h> 40#include <linux/atomic.h>
41#include <asm/cpu.h> 41#include <asm/cpu.h>
42#include <asm/ginvt.h>
42#include <asm/processor.h> 43#include <asm/processor.h>
43#include <asm/idle.h> 44#include <asm/idle.h>
44#include <asm/r4k-timer.h> 45#include <asm/r4k-timer.h>
@@ -443,6 +444,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
443/* preload SMP state for boot cpu */ 444/* preload SMP state for boot cpu */
444void smp_prepare_boot_cpu(void) 445void smp_prepare_boot_cpu(void)
445{ 446{
447 if (mp_ops->prepare_boot_cpu)
448 mp_ops->prepare_boot_cpu();
446 set_cpu_possible(0, true); 449 set_cpu_possible(0, true);
447 set_cpu_online(0, true); 450 set_cpu_online(0, true);
448} 451}
@@ -482,12 +485,21 @@ static void flush_tlb_all_ipi(void *info)
482 485
483void flush_tlb_all(void) 486void flush_tlb_all(void)
484{ 487{
488 if (cpu_has_mmid) {
489 htw_stop();
490 ginvt_full();
491 sync_ginv();
492 instruction_hazard();
493 htw_start();
494 return;
495 }
496
485 on_each_cpu(flush_tlb_all_ipi, NULL, 1); 497 on_each_cpu(flush_tlb_all_ipi, NULL, 1);
486} 498}
487 499
488static void flush_tlb_mm_ipi(void *mm) 500static void flush_tlb_mm_ipi(void *mm)
489{ 501{
490 local_flush_tlb_mm((struct mm_struct *)mm); 502 drop_mmu_context((struct mm_struct *)mm);
491} 503}
492 504
493/* 505/*
@@ -530,17 +542,22 @@ void flush_tlb_mm(struct mm_struct *mm)
530{ 542{
531 preempt_disable(); 543 preempt_disable();
532 544
533 if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { 545 if (cpu_has_mmid) {
546 /*
547 * No need to worry about other CPUs - the ginvt in
548 * drop_mmu_context() will be globalized.
549 */
550 } else if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
534 smp_on_other_tlbs(flush_tlb_mm_ipi, mm); 551 smp_on_other_tlbs(flush_tlb_mm_ipi, mm);
535 } else { 552 } else {
536 unsigned int cpu; 553 unsigned int cpu;
537 554
538 for_each_online_cpu(cpu) { 555 for_each_online_cpu(cpu) {
539 if (cpu != smp_processor_id() && cpu_context(cpu, mm)) 556 if (cpu != smp_processor_id() && cpu_context(cpu, mm))
540 cpu_context(cpu, mm) = 0; 557 set_cpu_context(cpu, mm, 0);
541 } 558 }
542 } 559 }
543 local_flush_tlb_mm(mm); 560 drop_mmu_context(mm);
544 561
545 preempt_enable(); 562 preempt_enable();
546} 563}
@@ -561,9 +578,26 @@ static void flush_tlb_range_ipi(void *info)
561void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) 578void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
562{ 579{
563 struct mm_struct *mm = vma->vm_mm; 580 struct mm_struct *mm = vma->vm_mm;
581 unsigned long addr;
582 u32 old_mmid;
564 583
565 preempt_disable(); 584 preempt_disable();
566 if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { 585 if (cpu_has_mmid) {
586 htw_stop();
587 old_mmid = read_c0_memorymapid();
588 write_c0_memorymapid(cpu_asid(0, mm));
589 mtc0_tlbw_hazard();
590 addr = round_down(start, PAGE_SIZE * 2);
591 end = round_up(end, PAGE_SIZE * 2);
592 do {
593 ginvt_va_mmid(addr);
594 sync_ginv();
595 addr += PAGE_SIZE * 2;
596 } while (addr < end);
597 write_c0_memorymapid(old_mmid);
598 instruction_hazard();
599 htw_start();
600 } else if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
567 struct flush_tlb_data fd = { 601 struct flush_tlb_data fd = {
568 .vma = vma, 602 .vma = vma,
569 .addr1 = start, 603 .addr1 = start,
@@ -571,6 +605,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l
571 }; 605 };
572 606
573 smp_on_other_tlbs(flush_tlb_range_ipi, &fd); 607 smp_on_other_tlbs(flush_tlb_range_ipi, &fd);
608 local_flush_tlb_range(vma, start, end);
574 } else { 609 } else {
575 unsigned int cpu; 610 unsigned int cpu;
576 int exec = vma->vm_flags & VM_EXEC; 611 int exec = vma->vm_flags & VM_EXEC;
@@ -583,10 +618,10 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l
583 * mm has been completely unused by that CPU. 618 * mm has been completely unused by that CPU.
584 */ 619 */
585 if (cpu != smp_processor_id() && cpu_context(cpu, mm)) 620 if (cpu != smp_processor_id() && cpu_context(cpu, mm))
586 cpu_context(cpu, mm) = !exec; 621 set_cpu_context(cpu, mm, !exec);
587 } 622 }
623 local_flush_tlb_range(vma, start, end);
588 } 624 }
589 local_flush_tlb_range(vma, start, end);
590 preempt_enable(); 625 preempt_enable();
591} 626}
592 627
@@ -616,14 +651,28 @@ static void flush_tlb_page_ipi(void *info)
616 651
617void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 652void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
618{ 653{
654 u32 old_mmid;
655
619 preempt_disable(); 656 preempt_disable();
620 if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) { 657 if (cpu_has_mmid) {
658 htw_stop();
659 old_mmid = read_c0_memorymapid();
660 write_c0_memorymapid(cpu_asid(0, vma->vm_mm));
661 mtc0_tlbw_hazard();
662 ginvt_va_mmid(page);
663 sync_ginv();
664 write_c0_memorymapid(old_mmid);
665 instruction_hazard();
666 htw_start();
667 } else if ((atomic_read(&vma->vm_mm->mm_users) != 1) ||
668 (current->mm != vma->vm_mm)) {
621 struct flush_tlb_data fd = { 669 struct flush_tlb_data fd = {
622 .vma = vma, 670 .vma = vma,
623 .addr1 = page, 671 .addr1 = page,
624 }; 672 };
625 673
626 smp_on_other_tlbs(flush_tlb_page_ipi, &fd); 674 smp_on_other_tlbs(flush_tlb_page_ipi, &fd);
675 local_flush_tlb_page(vma, page);
627 } else { 676 } else {
628 unsigned int cpu; 677 unsigned int cpu;
629 678
@@ -635,10 +684,10 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
635 * by that CPU. 684 * by that CPU.
636 */ 685 */
637 if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm)) 686 if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm))
638 cpu_context(cpu, vma->vm_mm) = 1; 687 set_cpu_context(cpu, vma->vm_mm, 1);
639 } 688 }
689 local_flush_tlb_page(vma, page);
640 } 690 }
641 local_flush_tlb_page(vma, page);
642 preempt_enable(); 691 preempt_enable();
643} 692}
644 693
diff --git a/arch/mips/kernel/spinlock_test.c b/arch/mips/kernel/spinlock_test.c
index eaed550e79a2..ab4e3e1b138d 100644
--- a/arch/mips/kernel/spinlock_test.c
+++ b/arch/mips/kernel/spinlock_test.c
@@ -118,23 +118,10 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n");
118 118
119static int __init spinlock_test(void) 119static int __init spinlock_test(void)
120{ 120{
121 struct dentry *d; 121 debugfs_create_file("spin_single", S_IRUGO, mips_debugfs_dir, NULL,
122 122 &fops_ss);
123 if (!mips_debugfs_dir) 123 debugfs_create_file("spin_multi", S_IRUGO, mips_debugfs_dir, NULL,
124 return -ENODEV; 124 &fops_multi);
125
126 d = debugfs_create_file("spin_single", S_IRUGO,
127 mips_debugfs_dir, NULL,
128 &fops_ss);
129 if (!d)
130 return -ENOMEM;
131
132 d = debugfs_create_file("spin_multi", S_IRUGO,
133 mips_debugfs_dir, NULL,
134 &fops_multi);
135 if (!d)
136 return -ENOMEM;
137
138 return 0; 125 return 0;
139} 126}
140device_initcall(spinlock_test); 127device_initcall(spinlock_test);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cbab46004e99..42d411125690 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -2223,7 +2223,9 @@ void per_cpu_trap_init(bool is_boot_cpu)
2223 cp0_fdc_irq = -1; 2223 cp0_fdc_irq = -1;
2224 } 2224 }
2225 2225
2226 if (!cpu_data[cpu].asid_cache) 2226 if (cpu_has_mmid)
2227 cpu_data[cpu].asid_cache = 0;
2228 else if (!cpu_data[cpu].asid_cache)
2227 cpu_data[cpu].asid_cache = asid_first_version(cpu); 2229 cpu_data[cpu].asid_cache = asid_first_version(cpu);
2228 2230
2229 mmgrab(&init_mm); 2231 mmgrab(&init_mm);
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 595ca9c85111..76e33f940971 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -89,6 +89,7 @@
89#include <asm/fpu.h> 89#include <asm/fpu.h>
90#include <asm/fpu_emulator.h> 90#include <asm/fpu_emulator.h>
91#include <asm/inst.h> 91#include <asm/inst.h>
92#include <asm/mmu_context.h>
92#include <linux/uaccess.h> 93#include <linux/uaccess.h>
93 94
94#define STR(x) __STR(x) 95#define STR(x) __STR(x)
@@ -2374,18 +2375,10 @@ sigbus:
2374#ifdef CONFIG_DEBUG_FS 2375#ifdef CONFIG_DEBUG_FS
2375static int __init debugfs_unaligned(void) 2376static int __init debugfs_unaligned(void)
2376{ 2377{
2377 struct dentry *d; 2378 debugfs_create_u32("unaligned_instructions", S_IRUGO, mips_debugfs_dir,
2378 2379 &unaligned_instructions);
2379 if (!mips_debugfs_dir) 2380 debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
2380 return -ENODEV; 2381 mips_debugfs_dir, &unaligned_action);
2381 d = debugfs_create_u32("unaligned_instructions", S_IRUGO,
2382 mips_debugfs_dir, &unaligned_instructions);
2383 if (!d)
2384 return -ENOMEM;
2385 d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
2386 mips_debugfs_dir, &unaligned_action);
2387 if (!d)
2388 return -ENOMEM;
2389 return 0; 2382 return 0;
2390} 2383}
2391arch_initcall(debugfs_unaligned); 2384arch_initcall(debugfs_unaligned);
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index ec9ed23bca7f..0074427b04fb 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1016,10 +1016,10 @@ static void kvm_mips_change_entryhi(struct kvm_vcpu *vcpu,
1016 */ 1016 */
1017 preempt_disable(); 1017 preempt_disable();
1018 cpu = smp_processor_id(); 1018 cpu = smp_processor_id();
1019 get_new_mmu_context(kern_mm, cpu); 1019 get_new_mmu_context(kern_mm);
1020 for_each_possible_cpu(i) 1020 for_each_possible_cpu(i)
1021 if (i != cpu) 1021 if (i != cpu)
1022 cpu_context(i, kern_mm) = 0; 1022 set_cpu_context(i, kern_mm, 0);
1023 preempt_enable(); 1023 preempt_enable();
1024 } 1024 }
1025 kvm_write_c0_guest_entryhi(cop0, entryhi); 1025 kvm_write_c0_guest_entryhi(cop0, entryhi);
@@ -1090,8 +1090,8 @@ static void kvm_mips_invalidate_guest_tlb(struct kvm_vcpu *vcpu,
1090 if (i == cpu) 1090 if (i == cpu)
1091 continue; 1091 continue;
1092 if (user) 1092 if (user)
1093 cpu_context(i, user_mm) = 0; 1093 set_cpu_context(i, user_mm, 0);
1094 cpu_context(i, kern_mm) = 0; 1094 set_cpu_context(i, kern_mm, 0);
1095 } 1095 }
1096 1096
1097 preempt_enable(); 1097 preempt_enable();
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 3734cd58895e..6d0517ac18e5 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -1723,6 +1723,11 @@ static int __init kvm_mips_init(void)
1723{ 1723{
1724 int ret; 1724 int ret;
1725 1725
1726 if (cpu_has_mmid) {
1727 pr_warn("KVM does not yet support MMIDs. KVM Disabled\n");
1728 return -EOPNOTSUPP;
1729 }
1730
1726 ret = kvm_mips_entry_setup(); 1731 ret = kvm_mips_entry_setup();
1727 if (ret) 1732 if (ret)
1728 return ret; 1733 return ret;
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
index 6a0d7040d882..73daa6ad33af 100644
--- a/arch/mips/kvm/trap_emul.c
+++ b/arch/mips/kvm/trap_emul.c
@@ -1056,11 +1056,7 @@ static int kvm_trap_emul_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
1056 */ 1056 */
1057 if (current->flags & PF_VCPU) { 1057 if (current->flags & PF_VCPU) {
1058 mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm; 1058 mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm;
1059 if ((cpu_context(cpu, mm) ^ asid_cache(cpu)) & 1059 check_switch_mmu_context(mm);
1060 asid_version_mask(cpu))
1061 get_new_mmu_context(mm, cpu);
1062 write_c0_entryhi(cpu_asid(cpu, mm));
1063 TLBMISS_HANDLER_SETUP_PGD(mm->pgd);
1064 kvm_mips_suspend_mm(cpu); 1060 kvm_mips_suspend_mm(cpu);
1065 ehb(); 1061 ehb();
1066 } 1062 }
@@ -1074,11 +1070,7 @@ static int kvm_trap_emul_vcpu_put(struct kvm_vcpu *vcpu, int cpu)
1074 1070
1075 if (current->flags & PF_VCPU) { 1071 if (current->flags & PF_VCPU) {
1076 /* Restore normal Linux process memory map */ 1072 /* Restore normal Linux process memory map */
1077 if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) & 1073 check_switch_mmu_context(current->mm);
1078 asid_version_mask(cpu)))
1079 get_new_mmu_context(current->mm, cpu);
1080 write_c0_entryhi(cpu_asid(cpu, current->mm));
1081 TLBMISS_HANDLER_SETUP_PGD(current->mm->pgd);
1082 kvm_mips_resume_mm(cpu); 1074 kvm_mips_resume_mm(cpu);
1083 ehb(); 1075 ehb();
1084 } 1076 }
@@ -1106,14 +1098,14 @@ static void kvm_trap_emul_check_requests(struct kvm_vcpu *vcpu, int cpu,
1106 kvm_mips_flush_gva_pt(kern_mm->pgd, KMF_GPA | KMF_KERN); 1098 kvm_mips_flush_gva_pt(kern_mm->pgd, KMF_GPA | KMF_KERN);
1107 kvm_mips_flush_gva_pt(user_mm->pgd, KMF_GPA | KMF_USER); 1099 kvm_mips_flush_gva_pt(user_mm->pgd, KMF_GPA | KMF_USER);
1108 for_each_possible_cpu(i) { 1100 for_each_possible_cpu(i) {
1109 cpu_context(i, kern_mm) = 0; 1101 set_cpu_context(i, kern_mm, 0);
1110 cpu_context(i, user_mm) = 0; 1102 set_cpu_context(i, user_mm, 0);
1111 } 1103 }
1112 1104
1113 /* Generate new ASID for current mode */ 1105 /* Generate new ASID for current mode */
1114 if (reload_asid) { 1106 if (reload_asid) {
1115 mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm; 1107 mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm;
1116 get_new_mmu_context(mm, cpu); 1108 get_new_mmu_context(mm);
1117 htw_stop(); 1109 htw_stop();
1118 write_c0_entryhi(cpu_asid(cpu, mm)); 1110 write_c0_entryhi(cpu_asid(cpu, mm));
1119 TLBMISS_HANDLER_SETUP_PGD(mm->pgd); 1111 TLBMISS_HANDLER_SETUP_PGD(mm->pgd);
@@ -1219,7 +1211,7 @@ static void kvm_trap_emul_vcpu_reenter(struct kvm_run *run,
1219 if (gasid != vcpu->arch.last_user_gasid) { 1211 if (gasid != vcpu->arch.last_user_gasid) {
1220 kvm_mips_flush_gva_pt(user_mm->pgd, KMF_USER); 1212 kvm_mips_flush_gva_pt(user_mm->pgd, KMF_USER);
1221 for_each_possible_cpu(i) 1213 for_each_possible_cpu(i)
1222 cpu_context(i, user_mm) = 0; 1214 set_cpu_context(i, user_mm, 0);
1223 vcpu->arch.last_user_gasid = gasid; 1215 vcpu->arch.last_user_gasid = gasid;
1224 } 1216 }
1225 } 1217 }
@@ -1228,9 +1220,7 @@ static void kvm_trap_emul_vcpu_reenter(struct kvm_run *run,
1228 * Check if ASID is stale. This may happen due to a TLB flush request or 1220 * Check if ASID is stale. This may happen due to a TLB flush request or
1229 * a lazy user MM invalidation. 1221 * a lazy user MM invalidation.
1230 */ 1222 */
1231 if ((cpu_context(cpu, mm) ^ asid_cache(cpu)) & 1223 check_mmu_context(mm);
1232 asid_version_mask(cpu))
1233 get_new_mmu_context(mm, cpu);
1234} 1224}
1235 1225
1236static int kvm_trap_emul_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) 1226static int kvm_trap_emul_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu)
@@ -1266,11 +1256,7 @@ static int kvm_trap_emul_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu)
1266 cpu = smp_processor_id(); 1256 cpu = smp_processor_id();
1267 1257
1268 /* Restore normal Linux process memory map */ 1258 /* Restore normal Linux process memory map */
1269 if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) & 1259 check_switch_mmu_context(current->mm);
1270 asid_version_mask(cpu)))
1271 get_new_mmu_context(current->mm, cpu);
1272 write_c0_entryhi(cpu_asid(cpu, current->mm));
1273 TLBMISS_HANDLER_SETUP_PGD(current->mm->pgd);
1274 kvm_mips_resume_mm(cpu); 1260 kvm_mips_resume_mm(cpu);
1275 1261
1276 htw_start(); 1262 htw_start();
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index 74805035edc8..dde20887a70d 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -2454,10 +2454,10 @@ static void kvm_vz_vcpu_load_tlb(struct kvm_vcpu *vcpu, int cpu)
2454 * Root ASID dealiases guest GPA mappings in the root TLB. 2454 * Root ASID dealiases guest GPA mappings in the root TLB.
2455 * Allocate new root ASID if needed. 2455 * Allocate new root ASID if needed.
2456 */ 2456 */
2457 if (cpumask_test_and_clear_cpu(cpu, &kvm->arch.asid_flush_mask) 2457 if (cpumask_test_and_clear_cpu(cpu, &kvm->arch.asid_flush_mask))
2458 || (cpu_context(cpu, gpa_mm) ^ asid_cache(cpu)) & 2458 get_new_mmu_context(gpa_mm);
2459 asid_version_mask(cpu)) 2459 else
2460 get_new_mmu_context(gpa_mm, cpu); 2460 check_mmu_context(gpa_mm);
2461 } 2461 }
2462} 2462}
2463 2463
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index 188de95d6dbd..6c6802e482c9 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -52,8 +52,4 @@ config PCI_LANTIQ
52 bool "PCI Support" 52 bool "PCI Support"
53 depends on SOC_XWAY && PCI 53 depends on SOC_XWAY && PCI
54 54
55config XRX200_PHY_FW
56 bool "XRX200 PHY firmware loader"
57 depends on SOC_XWAY
58
59endif 55endif
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 781ad96b78c4..83ed37298e66 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -10,6 +10,7 @@
10 10
11#include <asm/hazards.h> 11#include <asm/hazards.h>
12#include <asm/mipsregs.h> 12#include <asm/mipsregs.h>
13#include <asm/mmu_context.h>
13#include <asm/page.h> 14#include <asm/page.h>
14#include <asm/pgtable.h> 15#include <asm/pgtable.h>
15#include <asm/tlbdebug.h> 16#include <asm/tlbdebug.h>
@@ -73,12 +74,13 @@ static inline const char *msk2str(unsigned int mask)
73 74
74static void dump_tlb(int first, int last) 75static void dump_tlb(int first, int last)
75{ 76{
76 unsigned long s_entryhi, entryhi, asid; 77 unsigned long s_entryhi, entryhi, asid, mmid;
77 unsigned long long entrylo0, entrylo1, pa; 78 unsigned long long entrylo0, entrylo1, pa;
78 unsigned int s_index, s_pagemask, s_guestctl1 = 0; 79 unsigned int s_index, s_pagemask, s_guestctl1 = 0;
79 unsigned int pagemask, guestctl1 = 0, c0, c1, i; 80 unsigned int pagemask, guestctl1 = 0, c0, c1, i;
80 unsigned long asidmask = cpu_asid_mask(&current_cpu_data); 81 unsigned long asidmask = cpu_asid_mask(&current_cpu_data);
81 int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4); 82 int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4);
83 unsigned long uninitialized_var(s_mmid);
82#ifdef CONFIG_32BIT 84#ifdef CONFIG_32BIT
83 bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA); 85 bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA);
84 int pwidth = xpa ? 11 : 8; 86 int pwidth = xpa ? 11 : 8;
@@ -92,7 +94,12 @@ static void dump_tlb(int first, int last)
92 s_pagemask = read_c0_pagemask(); 94 s_pagemask = read_c0_pagemask();
93 s_entryhi = read_c0_entryhi(); 95 s_entryhi = read_c0_entryhi();
94 s_index = read_c0_index(); 96 s_index = read_c0_index();
95 asid = s_entryhi & asidmask; 97
98 if (cpu_has_mmid)
99 asid = s_mmid = read_c0_memorymapid();
100 else
101 asid = s_entryhi & asidmask;
102
96 if (cpu_has_guestid) 103 if (cpu_has_guestid)
97 s_guestctl1 = read_c0_guestctl1(); 104 s_guestctl1 = read_c0_guestctl1();
98 105
@@ -105,6 +112,12 @@ static void dump_tlb(int first, int last)
105 entryhi = read_c0_entryhi(); 112 entryhi = read_c0_entryhi();
106 entrylo0 = read_c0_entrylo0(); 113 entrylo0 = read_c0_entrylo0();
107 entrylo1 = read_c0_entrylo1(); 114 entrylo1 = read_c0_entrylo1();
115
116 if (cpu_has_mmid)
117 mmid = read_c0_memorymapid();
118 else
119 mmid = entryhi & asidmask;
120
108 if (cpu_has_guestid) 121 if (cpu_has_guestid)
109 guestctl1 = read_c0_guestctl1(); 122 guestctl1 = read_c0_guestctl1();
110 123
@@ -124,8 +137,7 @@ static void dump_tlb(int first, int last)
124 * leave only a single G bit set after a machine check exception 137 * leave only a single G bit set after a machine check exception
125 * due to duplicate TLB entry. 138 * due to duplicate TLB entry.
126 */ 139 */
127 if (!((entrylo0 | entrylo1) & ENTRYLO_G) && 140 if (!((entrylo0 | entrylo1) & ENTRYLO_G) && (mmid != asid))
128 (entryhi & asidmask) != asid)
129 continue; 141 continue;
130 142
131 /* 143 /*
@@ -138,7 +150,7 @@ static void dump_tlb(int first, int last)
138 150
139 pr_cont("va=%0*lx asid=%0*lx", 151 pr_cont("va=%0*lx asid=%0*lx",
140 vwidth, (entryhi & ~0x1fffUL), 152 vwidth, (entryhi & ~0x1fffUL),
141 asidwidth, entryhi & asidmask); 153 asidwidth, mmid);
142 if (cpu_has_guestid) 154 if (cpu_has_guestid)
143 pr_cont(" gid=%02lx", 155 pr_cont(" gid=%02lx",
144 (guestctl1 & MIPS_GCTL1_RID) 156 (guestctl1 & MIPS_GCTL1_RID)
diff --git a/arch/mips/loongson32/Kconfig b/arch/mips/loongson32/Kconfig
index 462b126f45aa..6dacc1438906 100644
--- a/arch/mips/loongson32/Kconfig
+++ b/arch/mips/loongson32/Kconfig
@@ -15,7 +15,6 @@ config LOONGSON1_LS1B
15 select SYS_SUPPORTS_32BIT_KERNEL 15 select SYS_SUPPORTS_32BIT_KERNEL
16 select SYS_SUPPORTS_LITTLE_ENDIAN 16 select SYS_SUPPORTS_LITTLE_ENDIAN
17 select SYS_SUPPORTS_HIGHMEM 17 select SYS_SUPPORTS_HIGHMEM
18 select SYS_SUPPORTS_MIPS16
19 select SYS_HAS_EARLY_PRINTK 18 select SYS_HAS_EARLY_PRINTK
20 select USE_GENERIC_EARLY_PRINTK_8250 19 select USE_GENERIC_EARLY_PRINTK_8250
21 select COMMON_CLK 20 select COMMON_CLK
@@ -31,7 +30,6 @@ config LOONGSON1_LS1C
31 select SYS_SUPPORTS_32BIT_KERNEL 30 select SYS_SUPPORTS_32BIT_KERNEL
32 select SYS_SUPPORTS_LITTLE_ENDIAN 31 select SYS_SUPPORTS_LITTLE_ENDIAN
33 select SYS_SUPPORTS_HIGHMEM 32 select SYS_SUPPORTS_HIGHMEM
34 select SYS_SUPPORTS_MIPS16
35 select SYS_HAS_EARLY_PRINTK 33 select SYS_HAS_EARLY_PRINTK
36 select USE_GENERIC_EARLY_PRINTK_8250 34 select USE_GENERIC_EARLY_PRINTK_8250
37 select COMMON_CLK 35 select COMMON_CLK
diff --git a/arch/mips/loongson32/Platform b/arch/mips/loongson32/Platform
index a0dbb3b2f2de..333215593092 100644
--- a/arch/mips/loongson32/Platform
+++ b/arch/mips/loongson32/Platform
@@ -1,4 +1,4 @@
1cflags-$(CONFIG_CPU_LOONGSON1) += -march=mips32 -Wa,--trap 1cflags-$(CONFIG_CPU_LOONGSON1) += -march=mips32r2 -Wa,--trap
2platform-$(CONFIG_MACH_LOONGSON32) += loongson32/ 2platform-$(CONFIG_MACH_LOONGSON32) += loongson32/
3cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32 3cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32
4load-$(CONFIG_CPU_LOONGSON1) += 0xffffffff80100000 4load-$(CONFIG_CPU_LOONGSON1) += 0xffffffff80200000
diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c
index ac584c5823d0..0bf355c8bcb2 100644
--- a/arch/mips/loongson32/common/platform.c
+++ b/arch/mips/loongson32/common/platform.c
@@ -81,42 +81,6 @@ struct platform_device ls1x_cpufreq_pdev = {
81 }, 81 },
82}; 82};
83 83
84/* DMA */
85static struct resource ls1x_dma_resources[] = {
86 [0] = {
87 .start = LS1X_DMAC_BASE,
88 .end = LS1X_DMAC_BASE + SZ_4 - 1,
89 .flags = IORESOURCE_MEM,
90 },
91 [1] = {
92 .start = LS1X_DMA0_IRQ,
93 .end = LS1X_DMA0_IRQ,
94 .flags = IORESOURCE_IRQ,
95 },
96 [2] = {
97 .start = LS1X_DMA1_IRQ,
98 .end = LS1X_DMA1_IRQ,
99 .flags = IORESOURCE_IRQ,
100 },
101 [3] = {
102 .start = LS1X_DMA2_IRQ,
103 .end = LS1X_DMA2_IRQ,
104 .flags = IORESOURCE_IRQ,
105 },
106};
107
108struct platform_device ls1x_dma_pdev = {
109 .name = "ls1x-dma",
110 .id = -1,
111 .num_resources = ARRAY_SIZE(ls1x_dma_resources),
112 .resource = ls1x_dma_resources,
113};
114
115void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata)
116{
117 ls1x_dma_pdev.dev.platform_data = pdata;
118}
119
120/* Synopsys Ethernet GMAC */ 84/* Synopsys Ethernet GMAC */
121static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { 85static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
122 .phy_mask = 0, 86 .phy_mask = 0,
@@ -291,33 +255,6 @@ struct platform_device ls1x_gpio1_pdev = {
291 .resource = ls1x_gpio1_resources, 255 .resource = ls1x_gpio1_resources,
292}; 256};
293 257
294/* NAND Flash */
295static struct resource ls1x_nand_resources[] = {
296 [0] = {
297 .start = LS1X_NAND_BASE,
298 .end = LS1X_NAND_BASE + SZ_32 - 1,
299 .flags = IORESOURCE_MEM,
300 },
301 [1] = {
302 /* DMA channel 0 is dedicated to NAND */
303 .start = LS1X_DMA_CHANNEL0,
304 .end = LS1X_DMA_CHANNEL0,
305 .flags = IORESOURCE_DMA,
306 },
307};
308
309struct platform_device ls1x_nand_pdev = {
310 .name = "ls1x-nand",
311 .id = -1,
312 .num_resources = ARRAY_SIZE(ls1x_nand_resources),
313 .resource = ls1x_nand_resources,
314};
315
316void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata)
317{
318 ls1x_nand_pdev.dev.platform_data = pdata;
319}
320
321/* USB EHCI */ 258/* USB EHCI */
322static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); 259static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32);
323 260
diff --git a/arch/mips/loongson32/ls1b/board.c b/arch/mips/loongson32/ls1b/board.c
index 01aceaace314..447b15fc0a2b 100644
--- a/arch/mips/loongson32/ls1b/board.c
+++ b/arch/mips/loongson32/ls1b/board.c
@@ -16,30 +16,6 @@
16#include <nand.h> 16#include <nand.h>
17#include <platform.h> 17#include <platform.h>
18 18
19struct plat_ls1x_dma ls1x_dma_pdata = {
20 .nr_channels = 3,
21};
22
23static 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
36struct 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
43static const struct gpio_led ls1x_gpio_leds[] __initconst = { 19static const struct gpio_led ls1x_gpio_leds[] __initconst = {
44 { 20 {
45 .name = "LED9", 21 .name = "LED9",
@@ -64,13 +40,11 @@ static const struct gpio_led_platform_data ls1x_led_pdata __initconst = {
64static struct platform_device *ls1b_platform_devices[] __initdata = { 40static struct platform_device *ls1b_platform_devices[] __initdata = {
65 &ls1x_uart_pdev, 41 &ls1x_uart_pdev,
66 &ls1x_cpufreq_pdev, 42 &ls1x_cpufreq_pdev,
67 &ls1x_dma_pdev,
68 &ls1x_eth0_pdev, 43 &ls1x_eth0_pdev,
69 &ls1x_eth1_pdev, 44 &ls1x_eth1_pdev,
70 &ls1x_ehci_pdev, 45 &ls1x_ehci_pdev,
71 &ls1x_gpio0_pdev, 46 &ls1x_gpio0_pdev,
72 &ls1x_gpio1_pdev, 47 &ls1x_gpio1_pdev,
73 &ls1x_nand_pdev,
74 &ls1x_rtc_pdev, 48 &ls1x_rtc_pdev,
75 &ls1x_wdt_pdev, 49 &ls1x_wdt_pdev,
76}; 50};
@@ -78,8 +52,6 @@ static struct platform_device *ls1b_platform_devices[] __initdata = {
78static int __init ls1b_platform_init(void) 52static int __init ls1b_platform_init(void)
79{ 53{
80 ls1x_serial_set_uartclk(&ls1x_uart_pdev); 54 ls1x_serial_set_uartclk(&ls1x_uart_pdev);
81 ls1x_dma_set_platdata(&ls1x_dma_pdata);
82 ls1x_nand_set_platdata(&ls1x_nand_pdata);
83 55
84 gpio_led_register_device(-1, &ls1x_led_pdata); 56 gpio_led_register_device(-1, &ls1x_led_pdata);
85 57
diff --git a/arch/mips/math-emu/me-debugfs.c b/arch/mips/math-emu/me-debugfs.c
index 58798f527356..387724860fa6 100644
--- a/arch/mips/math-emu/me-debugfs.c
+++ b/arch/mips/math-emu/me-debugfs.c
@@ -189,32 +189,21 @@ static int __init debugfs_fpuemu(void)
189{ 189{
190 struct dentry *fpuemu_debugfs_base_dir; 190 struct dentry *fpuemu_debugfs_base_dir;
191 struct dentry *fpuemu_debugfs_inst_dir; 191 struct dentry *fpuemu_debugfs_inst_dir;
192 struct dentry *d, *reset_file;
193
194 if (!mips_debugfs_dir)
195 return -ENODEV;
196 192
197 fpuemu_debugfs_base_dir = debugfs_create_dir("fpuemustats", 193 fpuemu_debugfs_base_dir = debugfs_create_dir("fpuemustats",
198 mips_debugfs_dir); 194 mips_debugfs_dir);
199 if (!fpuemu_debugfs_base_dir)
200 return -ENOMEM;
201 195
202 reset_file = debugfs_create_file("fpuemustats_clear", 0444, 196 debugfs_create_file("fpuemustats_clear", 0444, mips_debugfs_dir, NULL,
203 mips_debugfs_dir, NULL, 197 &fpuemustats_clear_fops);
204 &fpuemustats_clear_fops);
205 if (!reset_file)
206 return -ENOMEM;
207 198
208#define FPU_EMU_STAT_OFFSET(m) \ 199#define FPU_EMU_STAT_OFFSET(m) \
209 offsetof(struct mips_fpu_emulator_stats, m) 200 offsetof(struct mips_fpu_emulator_stats, m)
210 201
211#define FPU_STAT_CREATE(m) \ 202#define FPU_STAT_CREATE(m) \
212do { \ 203do { \
213 d = debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \ 204 debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \
214 (void *)FPU_EMU_STAT_OFFSET(m), \ 205 (void *)FPU_EMU_STAT_OFFSET(m), \
215 &fops_fpuemu_stat); \ 206 &fops_fpuemu_stat); \
216 if (!d) \
217 return -ENOMEM; \
218} while (0) 207} while (0)
219 208
220 FPU_STAT_CREATE(emulated); 209 FPU_STAT_CREATE(emulated);
@@ -233,8 +222,6 @@ do { \
233 222
234 fpuemu_debugfs_inst_dir = debugfs_create_dir("instructions", 223 fpuemu_debugfs_inst_dir = debugfs_create_dir("instructions",
235 fpuemu_debugfs_base_dir); 224 fpuemu_debugfs_base_dir);
236 if (!fpuemu_debugfs_inst_dir)
237 return -ENOMEM;
238 225
239#define FPU_STAT_CREATE_EX(m) \ 226#define FPU_STAT_CREATE_EX(m) \
240do { \ 227do { \
@@ -242,11 +229,9 @@ do { \
242 \ 229 \
243 adjust_instruction_counter_name(name, #m); \ 230 adjust_instruction_counter_name(name, #m); \
244 \ 231 \
245 d = debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \ 232 debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \
246 (void *)FPU_EMU_STAT_OFFSET(m), \ 233 (void *)FPU_EMU_STAT_OFFSET(m), \
247 &fops_fpuemu_stat); \ 234 &fops_fpuemu_stat); \
248 if (!d) \
249 return -ENOMEM; \
250} while (0) 235} while (0)
251 236
252 FPU_STAT_CREATE_EX(abs_s); 237 FPU_STAT_CREATE_EX(abs_s);
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 3e5bb203c95a..f34d7ff5eb60 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -3,9 +3,19 @@
3# Makefile for the Linux/MIPS-specific parts of the memory manager. 3# Makefile for the Linux/MIPS-specific parts of the memory manager.
4# 4#
5 5
6obj-y += cache.o extable.o fault.o \ 6obj-y += cache.o
7 gup.o init.o mmap.o page.o page-funcs.o \ 7obj-y += context.o
8 pgtable.o tlbex.o tlbex-fault.o tlb-funcs.o 8obj-y += extable.o
9obj-y += fault.o
10obj-y += gup.o
11obj-y += init.o
12obj-y += mmap.o
13obj-y += page.o
14obj-y += page-funcs.o
15obj-y += pgtable.o
16obj-y += tlbex.o
17obj-y += tlbex-fault.o
18obj-y += tlb-funcs.o
9 19
10ifdef CONFIG_CPU_MICROMIPS 20ifdef CONFIG_CPU_MICROMIPS
11obj-y += uasm-micromips.o 21obj-y += uasm-micromips.o
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c
index 0e45b061e514..8064821e9805 100644
--- a/arch/mips/mm/c-octeon.c
+++ b/arch/mips/mm/c-octeon.c
@@ -128,23 +128,6 @@ static void octeon_flush_icache_range(unsigned long start, unsigned long end)
128 128
129 129
130/** 130/**
131 * Flush the icache for a trampoline. These are used for interrupt
132 * and exception hooking.
133 *
134 * @addr: Address to flush
135 */
136static void octeon_flush_cache_sigtramp(unsigned long addr)
137{
138 struct vm_area_struct *vma;
139
140 down_read(&current->mm->mmap_sem);
141 vma = find_vma(current->mm, addr);
142 octeon_flush_icache_all_cores(vma);
143 up_read(&current->mm->mmap_sem);
144}
145
146
147/**
148 * Flush a range out of a vma 131 * Flush a range out of a vma
149 * 132 *
150 * @vma: VMA to flush 133 * @vma: VMA to flush
@@ -289,7 +272,6 @@ void octeon_cache_init(void)
289 flush_cache_mm = octeon_flush_cache_mm; 272 flush_cache_mm = octeon_flush_cache_mm;
290 flush_cache_page = octeon_flush_cache_page; 273 flush_cache_page = octeon_flush_cache_page;
291 flush_cache_range = octeon_flush_cache_range; 274 flush_cache_range = octeon_flush_cache_range;
292 flush_cache_sigtramp = octeon_flush_cache_sigtramp;
293 flush_icache_all = octeon_flush_icache_all; 275 flush_icache_all = octeon_flush_icache_all;
294 flush_data_cache_page = octeon_flush_data_cache_page; 276 flush_data_cache_page = octeon_flush_data_cache_page;
295 flush_icache_range = octeon_flush_icache_range; 277 flush_icache_range = octeon_flush_icache_range;
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index 01848cdf2074..0ca401ddf3b7 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -274,30 +274,6 @@ static void r3k_flush_data_cache_page(unsigned long addr)
274{ 274{
275} 275}
276 276
277static void r3k_flush_cache_sigtramp(unsigned long addr)
278{
279 unsigned long flags;
280
281 pr_debug("csigtramp[%08lx]\n", addr);
282
283 flags = read_c0_status();
284
285 write_c0_status(flags&~ST0_IEC);
286
287 /* Fill the TLB to avoid an exception with caches isolated. */
288 asm( "lw\t$0, 0x000(%0)\n\t"
289 "lw\t$0, 0x004(%0)\n\t"
290 : : "r" (addr) );
291
292 write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
293
294 asm( "sb\t$0, 0x000(%0)\n\t"
295 "sb\t$0, 0x004(%0)\n\t"
296 : : "r" (addr) );
297
298 write_c0_status(flags);
299}
300
301static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size) 277static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size)
302{ 278{
303 BUG(); 279 BUG();
@@ -331,7 +307,6 @@ void r3k_cache_init(void)
331 307
332 __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range; 308 __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range;
333 309
334 flush_cache_sigtramp = r3k_flush_cache_sigtramp;
335 local_flush_data_cache_page = local_r3k_flush_data_cache_page; 310 local_flush_data_cache_page = local_r3k_flush_data_cache_page;
336 flush_data_cache_page = r3k_flush_data_cache_page; 311 flush_data_cache_page = r3k_flush_data_cache_page;
337 312
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index d0b64df51eb2..5166e38cd1c6 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -540,6 +540,9 @@ static inline int has_valid_asid(const struct mm_struct *mm, unsigned int type)
540 unsigned int i; 540 unsigned int i;
541 const cpumask_t *mask = cpu_present_mask; 541 const cpumask_t *mask = cpu_present_mask;
542 542
543 if (cpu_has_mmid)
544 return cpu_context(0, mm) != 0;
545
543 /* cpu_sibling_map[] undeclared when !CONFIG_SMP */ 546 /* cpu_sibling_map[] undeclared when !CONFIG_SMP */
544#ifdef CONFIG_SMP 547#ifdef CONFIG_SMP
545 /* 548 /*
@@ -697,10 +700,7 @@ static inline void local_r4k_flush_cache_page(void *args)
697 } 700 }
698 if (exec) { 701 if (exec) {
699 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { 702 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
700 int cpu = smp_processor_id(); 703 drop_mmu_context(mm);
701
702 if (cpu_context(cpu, mm) != 0)
703 drop_mmu_context(mm, cpu);
704 } else 704 } else
705 vaddr ? r4k_blast_icache_page(addr) : 705 vaddr ? r4k_blast_icache_page(addr) :
706 r4k_blast_icache_user_page(addr); 706 r4k_blast_icache_user_page(addr);
@@ -937,119 +937,6 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
937} 937}
938#endif /* CONFIG_DMA_NONCOHERENT */ 938#endif /* CONFIG_DMA_NONCOHERENT */
939 939
940struct flush_cache_sigtramp_args {
941 struct mm_struct *mm;
942 struct page *page;
943 unsigned long addr;
944};
945
946/*
947 * While we're protected against bad userland addresses we don't care
948 * very much about what happens in that case. Usually a segmentation
949 * fault will dump the process later on anyway ...
950 */
951static void local_r4k_flush_cache_sigtramp(void *args)
952{
953 struct flush_cache_sigtramp_args *fcs_args = args;
954 unsigned long addr = fcs_args->addr;
955 struct page *page = fcs_args->page;
956 struct mm_struct *mm = fcs_args->mm;
957 int map_coherent = 0;
958 void *vaddr;
959
960 unsigned long ic_lsize = cpu_icache_line_size();
961 unsigned long dc_lsize = cpu_dcache_line_size();
962 unsigned long sc_lsize = cpu_scache_line_size();
963
964 /*
965 * If owns no valid ASID yet, cannot possibly have gotten
966 * this page into the cache.
967 */
968 if (!has_valid_asid(mm, R4K_HIT))
969 return;
970
971 if (mm == current->active_mm) {
972 vaddr = NULL;
973 } else {
974 /*
975 * Use kmap_coherent or kmap_atomic to do flushes for
976 * another ASID than the current one.
977 */
978 map_coherent = (cpu_has_dc_aliases &&
979 page_mapcount(page) &&
980 !Page_dcache_dirty(page));
981 if (map_coherent)
982 vaddr = kmap_coherent(page, addr);
983 else
984 vaddr = kmap_atomic(page);
985 addr = (unsigned long)vaddr + (addr & ~PAGE_MASK);
986 }
987
988 R4600_HIT_CACHEOP_WAR_IMPL;
989 if (!cpu_has_ic_fills_f_dc) {
990 if (dc_lsize)
991 vaddr ? flush_dcache_line(addr & ~(dc_lsize - 1))
992 : protected_writeback_dcache_line(
993 addr & ~(dc_lsize - 1));
994 if (!cpu_icache_snoops_remote_store && scache_size)
995 vaddr ? flush_scache_line(addr & ~(sc_lsize - 1))
996 : protected_writeback_scache_line(
997 addr & ~(sc_lsize - 1));
998 }
999 if (ic_lsize)
1000 vaddr ? flush_icache_line(addr & ~(ic_lsize - 1))
1001 : protected_flush_icache_line(addr & ~(ic_lsize - 1));
1002
1003 if (vaddr) {
1004 if (map_coherent)
1005 kunmap_coherent();
1006 else
1007 kunmap_atomic(vaddr);
1008 }
1009
1010 if (MIPS4K_ICACHE_REFILL_WAR) {
1011 __asm__ __volatile__ (
1012 ".set push\n\t"
1013 ".set noat\n\t"
1014 ".set "MIPS_ISA_LEVEL"\n\t"
1015#ifdef CONFIG_32BIT
1016 "la $at,1f\n\t"
1017#endif
1018#ifdef CONFIG_64BIT
1019 "dla $at,1f\n\t"
1020#endif
1021 "cache %0,($at)\n\t"
1022 "nop; nop; nop\n"
1023 "1:\n\t"
1024 ".set pop"
1025 :
1026 : "i" (Hit_Invalidate_I));
1027 }
1028 if (MIPS_CACHE_SYNC_WAR)
1029 __asm__ __volatile__ ("sync");
1030}
1031
1032static void r4k_flush_cache_sigtramp(unsigned long addr)
1033{
1034 struct flush_cache_sigtramp_args args;
1035 int npages;
1036
1037 down_read(&current->mm->mmap_sem);
1038
1039 npages = get_user_pages_fast(addr, 1, 0, &args.page);
1040 if (npages < 1)
1041 goto out;
1042
1043 args.mm = current->mm;
1044 args.addr = addr;
1045
1046 r4k_on_each_cpu(R4K_HIT, local_r4k_flush_cache_sigtramp, &args);
1047
1048 put_page(args.page);
1049out:
1050 up_read(&current->mm->mmap_sem);
1051}
1052
1053static void r4k_flush_icache_all(void) 940static void r4k_flush_icache_all(void)
1054{ 941{
1055 if (cpu_has_vtag_icache) 942 if (cpu_has_vtag_icache)
@@ -1978,7 +1865,6 @@ void r4k_cache_init(void)
1978 1865
1979 __flush_kernel_vmap_range = r4k_flush_kernel_vmap_range; 1866 __flush_kernel_vmap_range = r4k_flush_kernel_vmap_range;
1980 1867
1981 flush_cache_sigtramp = r4k_flush_cache_sigtramp;
1982 flush_icache_all = r4k_flush_icache_all; 1868 flush_icache_all = r4k_flush_icache_all;
1983 local_flush_data_cache_page = local_r4k_flush_data_cache_page; 1869 local_flush_data_cache_page = local_r4k_flush_data_cache_page;
1984 flush_data_cache_page = r4k_flush_data_cache_page; 1870 flush_data_cache_page = r4k_flush_data_cache_page;
@@ -2033,7 +1919,6 @@ void r4k_cache_init(void)
2033 /* I$ fills from D$ just by emptying the write buffers */ 1919 /* I$ fills from D$ just by emptying the write buffers */
2034 flush_cache_page = (void *)b5k_instruction_hazard; 1920 flush_cache_page = (void *)b5k_instruction_hazard;
2035 flush_cache_range = (void *)b5k_instruction_hazard; 1921 flush_cache_range = (void *)b5k_instruction_hazard;
2036 flush_cache_sigtramp = (void *)b5k_instruction_hazard;
2037 local_flush_data_cache_page = (void *)b5k_instruction_hazard; 1922 local_flush_data_cache_page = (void *)b5k_instruction_hazard;
2038 flush_data_cache_page = (void *)b5k_instruction_hazard; 1923 flush_data_cache_page = (void *)b5k_instruction_hazard;
2039 flush_icache_range = (void *)b5k_instruction_hazard; 1924 flush_icache_range = (void *)b5k_instruction_hazard;
@@ -2052,7 +1937,6 @@ void r4k_cache_init(void)
2052 flush_cache_mm = (void *)cache_noop; 1937 flush_cache_mm = (void *)cache_noop;
2053 flush_cache_page = (void *)cache_noop; 1938 flush_cache_page = (void *)cache_noop;
2054 flush_cache_range = (void *)cache_noop; 1939 flush_cache_range = (void *)cache_noop;
2055 flush_cache_sigtramp = (void *)cache_noop;
2056 flush_icache_all = (void *)cache_noop; 1940 flush_icache_all = (void *)cache_noop;
2057 flush_data_cache_page = (void *)cache_noop; 1941 flush_data_cache_page = (void *)cache_noop;
2058 local_flush_data_cache_page = (void *)cache_noop; 1942 local_flush_data_cache_page = (void *)cache_noop;
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 5f6c099a9457..b7c8a9d79c35 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -290,25 +290,6 @@ static void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
290 } 290 }
291} 291}
292 292
293static void tx39_flush_cache_sigtramp(unsigned long addr)
294{
295 unsigned long ic_lsize = current_cpu_data.icache.linesz;
296 unsigned long dc_lsize = current_cpu_data.dcache.linesz;
297 unsigned long config;
298 unsigned long flags;
299
300 protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
301
302 /* disable icache (set ICE#) */
303 local_irq_save(flags);
304 config = read_c0_conf();
305 write_c0_conf(config & ~TX39_CONF_ICE);
306 TX39_STOP_STREAMING();
307 protected_flush_icache_line(addr & ~(ic_lsize - 1));
308 write_c0_conf(config);
309 local_irq_restore(flags);
310}
311
312static __init void tx39_probe_cache(void) 293static __init void tx39_probe_cache(void)
313{ 294{
314 unsigned long config; 295 unsigned long config;
@@ -368,7 +349,6 @@ void tx39_cache_init(void)
368 flush_icache_range = (void *) tx39h_flush_icache_all; 349 flush_icache_range = (void *) tx39h_flush_icache_all;
369 local_flush_icache_range = (void *) tx39h_flush_icache_all; 350 local_flush_icache_range = (void *) tx39h_flush_icache_all;
370 351
371 flush_cache_sigtramp = (void *) tx39h_flush_icache_all;
372 local_flush_data_cache_page = (void *) tx39h_flush_icache_all; 352 local_flush_data_cache_page = (void *) tx39h_flush_icache_all;
373 flush_data_cache_page = (void *) tx39h_flush_icache_all; 353 flush_data_cache_page = (void *) tx39h_flush_icache_all;
374 354
@@ -397,7 +377,6 @@ void tx39_cache_init(void)
397 377
398 __flush_kernel_vmap_range = tx39_flush_kernel_vmap_range; 378 __flush_kernel_vmap_range = tx39_flush_kernel_vmap_range;
399 379
400 flush_cache_sigtramp = tx39_flush_cache_sigtramp;
401 local_flush_data_cache_page = local_tx39_flush_data_cache_page; 380 local_flush_data_cache_page = local_tx39_flush_data_cache_page;
402 flush_data_cache_page = tx39_flush_data_cache_page; 381 flush_data_cache_page = tx39_flush_data_cache_page;
403 382
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 55099fbff4e6..3da216988672 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -47,7 +47,6 @@ void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
47EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); 47EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
48 48
49/* MIPS specific cache operations */ 49/* MIPS specific cache operations */
50void (*flush_cache_sigtramp)(unsigned long addr);
51void (*local_flush_data_cache_page)(void * addr); 50void (*local_flush_data_cache_page)(void * addr);
52void (*flush_data_cache_page)(unsigned long addr); 51void (*flush_data_cache_page)(unsigned long addr);
53void (*flush_icache_all)(void); 52void (*flush_icache_all)(void);
diff --git a/arch/mips/mm/context.c b/arch/mips/mm/context.c
new file mode 100644
index 000000000000..b25564090939
--- /dev/null
+++ b/arch/mips/mm/context.c
@@ -0,0 +1,291 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/atomic.h>
3#include <linux/mmu_context.h>
4#include <linux/percpu.h>
5#include <linux/spinlock.h>
6
7static DEFINE_RAW_SPINLOCK(cpu_mmid_lock);
8
9static atomic64_t mmid_version;
10static unsigned int num_mmids;
11static unsigned long *mmid_map;
12
13static DEFINE_PER_CPU(u64, reserved_mmids);
14static cpumask_t tlb_flush_pending;
15
16static bool asid_versions_eq(int cpu, u64 a, u64 b)
17{
18 return ((a ^ b) & asid_version_mask(cpu)) == 0;
19}
20
21void get_new_mmu_context(struct mm_struct *mm)
22{
23 unsigned int cpu;
24 u64 asid;
25
26 /*
27 * This function is specific to ASIDs, and should not be called when
28 * MMIDs are in use.
29 */
30 if (WARN_ON(IS_ENABLED(CONFIG_DEBUG_VM) && cpu_has_mmid))
31 return;
32
33 cpu = smp_processor_id();
34 asid = asid_cache(cpu);
35
36 if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) {
37 if (cpu_has_vtag_icache)
38 flush_icache_all();
39 local_flush_tlb_all(); /* start new asid cycle */
40 }
41
42 set_cpu_context(cpu, mm, asid);
43 asid_cache(cpu) = asid;
44}
45EXPORT_SYMBOL_GPL(get_new_mmu_context);
46
47void check_mmu_context(struct mm_struct *mm)
48{
49 unsigned int cpu = smp_processor_id();
50
51 /*
52 * This function is specific to ASIDs, and should not be called when
53 * MMIDs are in use.
54 */
55 if (WARN_ON(IS_ENABLED(CONFIG_DEBUG_VM) && cpu_has_mmid))
56 return;
57
58 /* Check if our ASID is of an older version and thus invalid */
59 if (!asid_versions_eq(cpu, cpu_context(cpu, mm), asid_cache(cpu)))
60 get_new_mmu_context(mm);
61}
62EXPORT_SYMBOL_GPL(check_mmu_context);
63
64static void flush_context(void)
65{
66 u64 mmid;
67 int cpu;
68
69 /* Update the list of reserved MMIDs and the MMID bitmap */
70 bitmap_clear(mmid_map, 0, num_mmids);
71
72 /* Reserve an MMID for kmap/wired entries */
73 __set_bit(MMID_KERNEL_WIRED, mmid_map);
74
75 for_each_possible_cpu(cpu) {
76 mmid = xchg_relaxed(&cpu_data[cpu].asid_cache, 0);
77
78 /*
79 * If this CPU has already been through a
80 * rollover, but hasn't run another task in
81 * the meantime, we must preserve its reserved
82 * MMID, as this is the only trace we have of
83 * the process it is still running.
84 */
85 if (mmid == 0)
86 mmid = per_cpu(reserved_mmids, cpu);
87
88 __set_bit(mmid & cpu_asid_mask(&cpu_data[cpu]), mmid_map);
89 per_cpu(reserved_mmids, cpu) = mmid;
90 }
91
92 /*
93 * Queue a TLB invalidation for each CPU to perform on next
94 * context-switch
95 */
96 cpumask_setall(&tlb_flush_pending);
97}
98
99static bool check_update_reserved_mmid(u64 mmid, u64 newmmid)
100{
101 bool hit;
102 int cpu;
103
104 /*
105 * Iterate over the set of reserved MMIDs looking for a match.
106 * If we find one, then we can update our mm to use newmmid
107 * (i.e. the same MMID in the current generation) but we can't
108 * exit the loop early, since we need to ensure that all copies
109 * of the old MMID are updated to reflect the mm. Failure to do
110 * so could result in us missing the reserved MMID in a future
111 * generation.
112 */
113 hit = false;
114 for_each_possible_cpu(cpu) {
115 if (per_cpu(reserved_mmids, cpu) == mmid) {
116 hit = true;
117 per_cpu(reserved_mmids, cpu) = newmmid;
118 }
119 }
120
121 return hit;
122}
123
124static u64 get_new_mmid(struct mm_struct *mm)
125{
126 static u32 cur_idx = MMID_KERNEL_WIRED + 1;
127 u64 mmid, version, mmid_mask;
128
129 mmid = cpu_context(0, mm);
130 version = atomic64_read(&mmid_version);
131 mmid_mask = cpu_asid_mask(&boot_cpu_data);
132
133 if (!asid_versions_eq(0, mmid, 0)) {
134 u64 newmmid = version | (mmid & mmid_mask);
135
136 /*
137 * If our current MMID was active during a rollover, we
138 * can continue to use it and this was just a false alarm.
139 */
140 if (check_update_reserved_mmid(mmid, newmmid)) {
141 mmid = newmmid;
142 goto set_context;
143 }
144
145 /*
146 * We had a valid MMID in a previous life, so try to re-use
147 * it if possible.
148 */
149 if (!__test_and_set_bit(mmid & mmid_mask, mmid_map)) {
150 mmid = newmmid;
151 goto set_context;
152 }
153 }
154
155 /* Allocate a free MMID */
156 mmid = find_next_zero_bit(mmid_map, num_mmids, cur_idx);
157 if (mmid != num_mmids)
158 goto reserve_mmid;
159
160 /* We're out of MMIDs, so increment the global version */
161 version = atomic64_add_return_relaxed(asid_first_version(0),
162 &mmid_version);
163
164 /* Note currently active MMIDs & mark TLBs as requiring flushes */
165 flush_context();
166
167 /* We have more MMIDs than CPUs, so this will always succeed */
168 mmid = find_first_zero_bit(mmid_map, num_mmids);
169
170reserve_mmid:
171 __set_bit(mmid, mmid_map);
172 cur_idx = mmid;
173 mmid |= version;
174set_context:
175 set_cpu_context(0, mm, mmid);
176 return mmid;
177}
178
179void check_switch_mmu_context(struct mm_struct *mm)
180{
181 unsigned int cpu = smp_processor_id();
182 u64 ctx, old_active_mmid;
183 unsigned long flags;
184
185 if (!cpu_has_mmid) {
186 check_mmu_context(mm);
187 write_c0_entryhi(cpu_asid(cpu, mm));
188 goto setup_pgd;
189 }
190
191 /*
192 * MMID switch fast-path, to avoid acquiring cpu_mmid_lock when it's
193 * unnecessary.
194 *
195 * The memory ordering here is subtle. If our active_mmids is non-zero
196 * and the MMID matches the current version, then we update the CPU's
197 * asid_cache with a relaxed cmpxchg. Racing with a concurrent rollover
198 * means that either:
199 *
200 * - We get a zero back from the cmpxchg and end up waiting on
201 * cpu_mmid_lock in check_mmu_context(). Taking the lock synchronises
202 * with the rollover and so we are forced to see the updated
203 * generation.
204 *
205 * - We get a valid MMID back from the cmpxchg, which means the
206 * relaxed xchg in flush_context will treat us as reserved
207 * because atomic RmWs are totally ordered for a given location.
208 */
209 ctx = cpu_context(cpu, mm);
210 old_active_mmid = READ_ONCE(cpu_data[cpu].asid_cache);
211 if (!old_active_mmid ||
212 !asid_versions_eq(cpu, ctx, atomic64_read(&mmid_version)) ||
213 !cmpxchg_relaxed(&cpu_data[cpu].asid_cache, old_active_mmid, ctx)) {
214 raw_spin_lock_irqsave(&cpu_mmid_lock, flags);
215
216 ctx = cpu_context(cpu, mm);
217 if (!asid_versions_eq(cpu, ctx, atomic64_read(&mmid_version)))
218 ctx = get_new_mmid(mm);
219
220 WRITE_ONCE(cpu_data[cpu].asid_cache, ctx);
221 raw_spin_unlock_irqrestore(&cpu_mmid_lock, flags);
222 }
223
224 /*
225 * Invalidate the local TLB if needed. Note that we must only clear our
226 * bit in tlb_flush_pending after this is complete, so that the
227 * cpu_has_shared_ftlb_entries case below isn't misled.
228 */
229 if (cpumask_test_cpu(cpu, &tlb_flush_pending)) {
230 if (cpu_has_vtag_icache)
231 flush_icache_all();
232 local_flush_tlb_all();
233 cpumask_clear_cpu(cpu, &tlb_flush_pending);
234 }
235
236 write_c0_memorymapid(ctx & cpu_asid_mask(&boot_cpu_data));
237
238 /*
239 * If this CPU shares FTLB entries with its siblings and one or more of
240 * those siblings hasn't yet invalidated its TLB following a version
241 * increase then we need to invalidate any TLB entries for our MMID
242 * that we might otherwise pick up from a sibling.
243 *
244 * We ifdef on CONFIG_SMP because cpu_sibling_map isn't defined in
245 * CONFIG_SMP=n kernels.
246 */
247#ifdef CONFIG_SMP
248 if (cpu_has_shared_ftlb_entries &&
249 cpumask_intersects(&tlb_flush_pending, &cpu_sibling_map[cpu])) {
250 /* Ensure we operate on the new MMID */
251 mtc0_tlbw_hazard();
252
253 /*
254 * Invalidate all TLB entries associated with the new
255 * MMID, and wait for the invalidation to complete.
256 */
257 ginvt_mmid();
258 sync_ginv();
259 }
260#endif
261
262setup_pgd:
263 TLBMISS_HANDLER_SETUP_PGD(mm->pgd);
264}
265EXPORT_SYMBOL_GPL(check_switch_mmu_context);
266
267static int mmid_init(void)
268{
269 if (!cpu_has_mmid)
270 return 0;
271
272 /*
273 * Expect allocation after rollover to fail if we don't have at least
274 * one more MMID than CPUs.
275 */
276 num_mmids = asid_first_version(0);
277 WARN_ON(num_mmids <= num_possible_cpus());
278
279 atomic64_set(&mmid_version, asid_first_version(0));
280 mmid_map = kcalloc(BITS_TO_LONGS(num_mmids), sizeof(*mmid_map),
281 GFP_KERNEL);
282 if (!mmid_map)
283 panic("Failed to allocate bitmap for %u MMIDs\n", num_mmids);
284
285 /* Reserve an MMID for kmap/wired entries */
286 __set_bit(MMID_KERNEL_WIRED, mmid_map);
287
288 pr_info("MMID allocator initialised with %u entries\n", num_mmids);
289 return 0;
290}
291early_initcall(mmid_init);
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index cb38461391cb..b57465733e87 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -120,13 +120,8 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size,
120 if (PageHighMem(page)) { 120 if (PageHighMem(page)) {
121 void *addr; 121 void *addr;
122 122
123 if (offset + len > PAGE_SIZE) { 123 if (offset + len > PAGE_SIZE)
124 if (offset >= PAGE_SIZE) {
125 page += offset >> PAGE_SHIFT;
126 offset &= ~PAGE_MASK;
127 }
128 len = PAGE_SIZE - offset; 124 len = PAGE_SIZE - offset;
129 }
130 125
131 addr = kmap_atomic(page); 126 addr = kmap_atomic(page);
132 dma_sync_virt(addr + offset, len, dir); 127 dma_sync_virt(addr + offset, len, dir);
@@ -145,12 +140,14 @@ void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
145 dma_sync_phys(paddr, size, dir); 140 dma_sync_phys(paddr, size, dir);
146} 141}
147 142
143#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
148void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, 144void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
149 size_t size, enum dma_data_direction dir) 145 size_t size, enum dma_data_direction dir)
150{ 146{
151 if (cpu_needs_post_dma_flush(dev)) 147 if (cpu_needs_post_dma_flush(dev))
152 dma_sync_phys(paddr, size, dir); 148 dma_sync_phys(paddr, size, dir);
153} 149}
150#endif
154 151
155void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size, 152void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
156 enum dma_data_direction direction) 153 enum dma_data_direction direction)
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index b521d8e2d359..c3b45e248806 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -84,6 +84,7 @@ void setup_zero_pages(void)
84static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) 84static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
85{ 85{
86 enum fixed_addresses idx; 86 enum fixed_addresses idx;
87 unsigned int uninitialized_var(old_mmid);
87 unsigned long vaddr, flags, entrylo; 88 unsigned long vaddr, flags, entrylo;
88 unsigned long old_ctx; 89 unsigned long old_ctx;
89 pte_t pte; 90 pte_t pte;
@@ -110,6 +111,10 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
110 write_c0_entryhi(vaddr & (PAGE_MASK << 1)); 111 write_c0_entryhi(vaddr & (PAGE_MASK << 1));
111 write_c0_entrylo0(entrylo); 112 write_c0_entrylo0(entrylo);
112 write_c0_entrylo1(entrylo); 113 write_c0_entrylo1(entrylo);
114 if (cpu_has_mmid) {
115 old_mmid = read_c0_memorymapid();
116 write_c0_memorymapid(MMID_KERNEL_WIRED);
117 }
113#ifdef CONFIG_XPA 118#ifdef CONFIG_XPA
114 if (cpu_has_xpa) { 119 if (cpu_has_xpa) {
115 entrylo = (pte.pte_low & _PFNX_MASK); 120 entrylo = (pte.pte_low & _PFNX_MASK);
@@ -124,6 +129,8 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
124 tlb_write_indexed(); 129 tlb_write_indexed();
125 tlbw_use_hazard(); 130 tlbw_use_hazard();
126 write_c0_entryhi(old_ctx); 131 write_c0_entryhi(old_ctx);
132 if (cpu_has_mmid)
133 write_c0_memorymapid(old_mmid);
127 local_irq_restore(flags); 134 local_irq_restore(flags);
128 135
129 return (void*) vaddr; 136 return (void*) vaddr;
diff --git a/arch/mips/mm/sc-debugfs.c b/arch/mips/mm/sc-debugfs.c
index 2a116084216f..9507421de335 100644
--- a/arch/mips/mm/sc-debugfs.c
+++ b/arch/mips/mm/sc-debugfs.c
@@ -55,20 +55,11 @@ static const struct file_operations sc_prefetch_fops = {
55 55
56static int __init sc_debugfs_init(void) 56static int __init sc_debugfs_init(void)
57{ 57{
58 struct dentry *dir, *file; 58 struct dentry *dir;
59
60 if (!mips_debugfs_dir)
61 return -ENODEV;
62 59
63 dir = debugfs_create_dir("l2cache", mips_debugfs_dir); 60 dir = debugfs_create_dir("l2cache", mips_debugfs_dir);
64 if (IS_ERR(dir)) 61 debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir, NULL,
65 return PTR_ERR(dir); 62 &sc_prefetch_fops);
66
67 file = debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir,
68 NULL, &sc_prefetch_fops);
69 if (!file)
70 return -ENOMEM;
71
72 return 0; 63 return 0;
73} 64}
74late_initcall(sc_debugfs_init); 65late_initcall(sc_debugfs_init);
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c
index 6f589e0112ce..50f207591b6d 100644
--- a/arch/mips/mm/tlb-r3k.c
+++ b/arch/mips/mm/tlb-r3k.c
@@ -67,18 +67,6 @@ void local_flush_tlb_all(void)
67 local_irq_restore(flags); 67 local_irq_restore(flags);
68} 68}
69 69
70void local_flush_tlb_mm(struct mm_struct *mm)
71{
72 int cpu = smp_processor_id();
73
74 if (cpu_context(cpu, mm) != 0) {
75#ifdef DEBUG_TLB
76 printk("[tlbmm<%lu>]", (unsigned long)cpu_context(cpu, mm));
77#endif
78 drop_mmu_context(mm, cpu);
79 }
80}
81
82void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 70void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
83 unsigned long end) 71 unsigned long end)
84{ 72{
@@ -117,7 +105,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
117 } 105 }
118 write_c0_entryhi(oldpid); 106 write_c0_entryhi(oldpid);
119 } else { 107 } else {
120 drop_mmu_context(mm, cpu); 108 drop_mmu_context(mm);
121 } 109 }
122 local_irq_restore(flags); 110 local_irq_restore(flags);
123 } 111 }
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 0596505770db..c13e46ced425 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -104,23 +104,6 @@ void local_flush_tlb_all(void)
104} 104}
105EXPORT_SYMBOL(local_flush_tlb_all); 105EXPORT_SYMBOL(local_flush_tlb_all);
106 106
107/* All entries common to a mm share an asid. To effectively flush
108 these entries, we just bump the asid. */
109void local_flush_tlb_mm(struct mm_struct *mm)
110{
111 int cpu;
112
113 preempt_disable();
114
115 cpu = smp_processor_id();
116
117 if (cpu_context(cpu, mm) != 0) {
118 drop_mmu_context(mm, cpu);
119 }
120
121 preempt_enable();
122}
123
124void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 107void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
125 unsigned long end) 108 unsigned long end)
126{ 109{
@@ -137,14 +120,23 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
137 if (size <= (current_cpu_data.tlbsizeftlbsets ? 120 if (size <= (current_cpu_data.tlbsizeftlbsets ?
138 current_cpu_data.tlbsize / 8 : 121 current_cpu_data.tlbsize / 8 :
139 current_cpu_data.tlbsize / 2)) { 122 current_cpu_data.tlbsize / 2)) {
140 int oldpid = read_c0_entryhi(); 123 unsigned long old_entryhi, uninitialized_var(old_mmid);
141 int newpid = cpu_asid(cpu, mm); 124 int newpid = cpu_asid(cpu, mm);
142 125
126 old_entryhi = read_c0_entryhi();
127 if (cpu_has_mmid) {
128 old_mmid = read_c0_memorymapid();
129 write_c0_memorymapid(newpid);
130 }
131
143 htw_stop(); 132 htw_stop();
144 while (start < end) { 133 while (start < end) {
145 int idx; 134 int idx;
146 135
147 write_c0_entryhi(start | newpid); 136 if (cpu_has_mmid)
137 write_c0_entryhi(start);
138 else
139 write_c0_entryhi(start | newpid);
148 start += (PAGE_SIZE << 1); 140 start += (PAGE_SIZE << 1);
149 mtc0_tlbw_hazard(); 141 mtc0_tlbw_hazard();
150 tlb_probe(); 142 tlb_probe();
@@ -160,10 +152,12 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
160 tlb_write_indexed(); 152 tlb_write_indexed();
161 } 153 }
162 tlbw_use_hazard(); 154 tlbw_use_hazard();
163 write_c0_entryhi(oldpid); 155 write_c0_entryhi(old_entryhi);
156 if (cpu_has_mmid)
157 write_c0_memorymapid(old_mmid);
164 htw_start(); 158 htw_start();
165 } else { 159 } else {
166 drop_mmu_context(mm, cpu); 160 drop_mmu_context(mm);
167 } 161 }
168 flush_micro_tlb(); 162 flush_micro_tlb();
169 local_irq_restore(flags); 163 local_irq_restore(flags);
@@ -220,15 +214,21 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
220 int cpu = smp_processor_id(); 214 int cpu = smp_processor_id();
221 215
222 if (cpu_context(cpu, vma->vm_mm) != 0) { 216 if (cpu_context(cpu, vma->vm_mm) != 0) {
223 unsigned long flags; 217 unsigned long uninitialized_var(old_mmid);
224 int oldpid, newpid, idx; 218 unsigned long flags, old_entryhi;
219 int idx;
225 220
226 newpid = cpu_asid(cpu, vma->vm_mm);
227 page &= (PAGE_MASK << 1); 221 page &= (PAGE_MASK << 1);
228 local_irq_save(flags); 222 local_irq_save(flags);
229 oldpid = read_c0_entryhi(); 223 old_entryhi = read_c0_entryhi();
230 htw_stop(); 224 htw_stop();
231 write_c0_entryhi(page | newpid); 225 if (cpu_has_mmid) {
226 old_mmid = read_c0_memorymapid();
227 write_c0_entryhi(page);
228 write_c0_memorymapid(cpu_asid(cpu, vma->vm_mm));
229 } else {
230 write_c0_entryhi(page | cpu_asid(cpu, vma->vm_mm));
231 }
232 mtc0_tlbw_hazard(); 232 mtc0_tlbw_hazard();
233 tlb_probe(); 233 tlb_probe();
234 tlb_probe_hazard(); 234 tlb_probe_hazard();
@@ -244,7 +244,9 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
244 tlbw_use_hazard(); 244 tlbw_use_hazard();
245 245
246 finish: 246 finish:
247 write_c0_entryhi(oldpid); 247 write_c0_entryhi(old_entryhi);
248 if (cpu_has_mmid)
249 write_c0_memorymapid(old_mmid);
248 htw_start(); 250 htw_start();
249 flush_micro_tlb_vm(vma); 251 flush_micro_tlb_vm(vma);
250 local_irq_restore(flags); 252 local_irq_restore(flags);
@@ -307,9 +309,13 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
307 local_irq_save(flags); 309 local_irq_save(flags);
308 310
309 htw_stop(); 311 htw_stop();
310 pid = read_c0_entryhi() & cpu_asid_mask(&current_cpu_data);
311 address &= (PAGE_MASK << 1); 312 address &= (PAGE_MASK << 1);
312 write_c0_entryhi(address | pid); 313 if (cpu_has_mmid) {
314 write_c0_entryhi(address);
315 } else {
316 pid = read_c0_entryhi() & cpu_asid_mask(&current_cpu_data);
317 write_c0_entryhi(address | pid);
318 }
313 pgdp = pgd_offset(vma->vm_mm, address); 319 pgdp = pgd_offset(vma->vm_mm, address);
314 mtc0_tlbw_hazard(); 320 mtc0_tlbw_hazard();
315 tlb_probe(); 321 tlb_probe();
@@ -375,12 +381,17 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
375#ifdef CONFIG_XPA 381#ifdef CONFIG_XPA
376 panic("Broken for XPA kernels"); 382 panic("Broken for XPA kernels");
377#else 383#else
384 unsigned int uninitialized_var(old_mmid);
378 unsigned long flags; 385 unsigned long flags;
379 unsigned long wired; 386 unsigned long wired;
380 unsigned long old_pagemask; 387 unsigned long old_pagemask;
381 unsigned long old_ctx; 388 unsigned long old_ctx;
382 389
383 local_irq_save(flags); 390 local_irq_save(flags);
391 if (cpu_has_mmid) {
392 old_mmid = read_c0_memorymapid();
393 write_c0_memorymapid(MMID_KERNEL_WIRED);
394 }
384 /* Save old context and create impossible VPN2 value */ 395 /* Save old context and create impossible VPN2 value */
385 old_ctx = read_c0_entryhi(); 396 old_ctx = read_c0_entryhi();
386 htw_stop(); 397 htw_stop();
@@ -398,6 +409,8 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
398 tlbw_use_hazard(); 409 tlbw_use_hazard();
399 410
400 write_c0_entryhi(old_ctx); 411 write_c0_entryhi(old_ctx);
412 if (cpu_has_mmid)
413 write_c0_memorymapid(old_mmid);
401 tlbw_use_hazard(); /* What is the hazard here? */ 414 tlbw_use_hazard(); /* What is the hazard here? */
402 htw_start(); 415 htw_start();
403 write_c0_pagemask(old_pagemask); 416 write_c0_pagemask(old_pagemask);
diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c
index e86e2e55ad3e..c1e9e144007e 100644
--- a/arch/mips/mm/tlb-r8k.c
+++ b/arch/mips/mm/tlb-r8k.c
@@ -50,14 +50,6 @@ void local_flush_tlb_all(void)
50 local_irq_restore(flags); 50 local_irq_restore(flags);
51} 51}
52 52
53void local_flush_tlb_mm(struct mm_struct *mm)
54{
55 int cpu = smp_processor_id();
56
57 if (cpu_context(cpu, mm) != 0)
58 drop_mmu_context(mm, cpu);
59}
60
61void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 53void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
62 unsigned long end) 54 unsigned long end)
63{ 55{
@@ -75,7 +67,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
75 local_irq_save(flags); 67 local_irq_save(flags);
76 68
77 if (size > TFP_TLB_SIZE / 2) { 69 if (size > TFP_TLB_SIZE / 2) {
78 drop_mmu_context(mm, cpu); 70 drop_mmu_context(mm);
79 goto out_restore; 71 goto out_restore;
80 } 72 }
81 73
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 8185a2bfaf09..c4f976593061 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
29# 29#
30# These are still pretty much in the old state, watch, go blind. 30# These are still pretty much in the old state, watch, go blind.
31# 31#
32obj-$(CONFIG_ATH79) += fixup-ath79.o
32obj-$(CONFIG_LASAT) += pci-lasat.o 33obj-$(CONFIG_LASAT) += pci-lasat.o
33obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o 34obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
34obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o 35obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o
diff --git a/arch/mips/pci/fixup-ath79.c b/arch/mips/pci/fixup-ath79.c
new file mode 100644
index 000000000000..9e651a4af05e
--- /dev/null
+++ b/arch/mips/pci/fixup-ath79.c
@@ -0,0 +1,21 @@
1/*
2 * Copyright (C) 2018 John Crispin <john@phrozen.org>
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 version 2 as published
6 * by the Free Software Foundation.
7 */
8
9#include <linux/pci.h>
10//#include <linux/of_irq.h>
11#include <linux/of_pci.h>
12
13int pcibios_plat_dev_init(struct pci_dev *dev)
14{
15 return PCIBIOS_SUCCESSFUL;
16}
17
18int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
19{
20 return of_irq_parse_and_map_pci(dev, slot, pin);
21}
diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c
index a1d2c4ae0d1b..df95b0da08f2 100644
--- a/arch/mips/pci/ops-bridge.c
+++ b/arch/mips/pci/ops-bridge.c
@@ -44,7 +44,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
44 int where, int size, u32 * value) 44 int where, int size, u32 * value)
45{ 45{
46 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 46 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
47 bridge_t *bridge = bc->base; 47 struct bridge_regs *bridge = bc->base;
48 int slot = PCI_SLOT(devfn); 48 int slot = PCI_SLOT(devfn);
49 int fn = PCI_FUNC(devfn); 49 int fn = PCI_FUNC(devfn);
50 volatile void *addr; 50 volatile void *addr;
@@ -56,11 +56,11 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
56 return PCIBIOS_DEVICE_NOT_FOUND; 56 return PCIBIOS_DEVICE_NOT_FOUND;
57 57
58 /* 58 /*
59 * IOC3 is fucking fucked beyond belief ... Don't even give the 59 * IOC3 is broken beyond belief ... Don't even give the
60 * generic PCI code a chance to look at it for real ... 60 * generic PCI code a chance to look at it for real ...
61 */ 61 */
62 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 62 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
63 goto oh_my_gawd; 63 goto is_ioc3;
64 64
65 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; 65 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
66 66
@@ -73,21 +73,16 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
73 73
74 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 74 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
75 75
76oh_my_gawd: 76is_ioc3:
77 77
78 /* 78 /*
79 * IOC3 is fucking fucked beyond belief ... Don't even give the 79 * IOC3 special handling
80 * generic PCI code a chance to look at the wrong register.
81 */ 80 */
82 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { 81 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
83 *value = emulate_ioc3_cfg(where, size); 82 *value = emulate_ioc3_cfg(where, size);
84 return PCIBIOS_SUCCESSFUL; 83 return PCIBIOS_SUCCESSFUL;
85 } 84 }
86 85
87 /*
88 * IOC3 is fucking fucked beyond belief ... Don't try to access
89 * anything but 32-bit words ...
90 */
91 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 86 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
92 87
93 if (get_dbe(cf, (u32 *) addr)) 88 if (get_dbe(cf, (u32 *) addr))
@@ -104,7 +99,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
104 int where, int size, u32 * value) 99 int where, int size, u32 * value)
105{ 100{
106 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 101 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
107 bridge_t *bridge = bc->base; 102 struct bridge_regs *bridge = bc->base;
108 int busno = bus->number; 103 int busno = bus->number;
109 int slot = PCI_SLOT(devfn); 104 int slot = PCI_SLOT(devfn);
110 int fn = PCI_FUNC(devfn); 105 int fn = PCI_FUNC(devfn);
@@ -112,19 +107,19 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
112 u32 cf, shift, mask; 107 u32 cf, shift, mask;
113 int res; 108 int res;
114 109
115 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 110 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
116 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; 111 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
117 if (get_dbe(cf, (u32 *) addr)) 112 if (get_dbe(cf, (u32 *) addr))
118 return PCIBIOS_DEVICE_NOT_FOUND; 113 return PCIBIOS_DEVICE_NOT_FOUND;
119 114
120 /* 115 /*
121 * IOC3 is fucking fucked beyond belief ... Don't even give the 116 * IOC3 is broken beyond belief ... Don't even give the
122 * generic PCI code a chance to look at it for real ... 117 * generic PCI code a chance to look at it for real ...
123 */ 118 */
124 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 119 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
125 goto oh_my_gawd; 120 goto is_ioc3;
126 121
127 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 122 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
128 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; 123 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
129 124
130 if (size == 1) 125 if (size == 1)
@@ -136,22 +131,17 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
136 131
137 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 132 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
138 133
139oh_my_gawd: 134is_ioc3:
140 135
141 /* 136 /*
142 * IOC3 is fucking fucked beyond belief ... Don't even give the 137 * IOC3 special handling
143 * generic PCI code a chance to look at the wrong register.
144 */ 138 */
145 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { 139 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
146 *value = emulate_ioc3_cfg(where, size); 140 *value = emulate_ioc3_cfg(where, size);
147 return PCIBIOS_SUCCESSFUL; 141 return PCIBIOS_SUCCESSFUL;
148 } 142 }
149 143
150 /* 144 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
151 * IOC3 is fucking fucked beyond belief ... Don't try to access
152 * anything but 32-bit words ...
153 */
154 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
155 addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; 145 addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
156 146
157 if (get_dbe(cf, (u32 *) addr)) 147 if (get_dbe(cf, (u32 *) addr))
@@ -177,7 +167,7 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
177 int where, int size, u32 value) 167 int where, int size, u32 value)
178{ 168{
179 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 169 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
180 bridge_t *bridge = bc->base; 170 struct bridge_regs *bridge = bc->base;
181 int slot = PCI_SLOT(devfn); 171 int slot = PCI_SLOT(devfn);
182 int fn = PCI_FUNC(devfn); 172 int fn = PCI_FUNC(devfn);
183 volatile void *addr; 173 volatile void *addr;
@@ -189,11 +179,11 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
189 return PCIBIOS_DEVICE_NOT_FOUND; 179 return PCIBIOS_DEVICE_NOT_FOUND;
190 180
191 /* 181 /*
192 * IOC3 is fucking fucked beyond belief ... Don't even give the 182 * IOC3 is broken beyond belief ... Don't even give the
193 * generic PCI code a chance to look at it for real ... 183 * generic PCI code a chance to look at it for real ...
194 */ 184 */
195 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 185 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
196 goto oh_my_gawd; 186 goto is_ioc3;
197 187
198 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; 188 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
199 189
@@ -210,19 +200,14 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
210 200
211 return PCIBIOS_SUCCESSFUL; 201 return PCIBIOS_SUCCESSFUL;
212 202
213oh_my_gawd: 203is_ioc3:
214 204
215 /* 205 /*
216 * IOC3 is fucking fucked beyond belief ... Don't even give the 206 * IOC3 special handling
217 * generic PCI code a chance to touch the wrong register.
218 */ 207 */
219 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 208 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
220 return PCIBIOS_SUCCESSFUL; 209 return PCIBIOS_SUCCESSFUL;
221 210
222 /*
223 * IOC3 is fucking fucked beyond belief ... Don't try to access
224 * anything but 32-bit words ...
225 */
226 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 211 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
227 212
228 if (get_dbe(cf, (u32 *) addr)) 213 if (get_dbe(cf, (u32 *) addr))
@@ -243,7 +228,7 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
243 int where, int size, u32 value) 228 int where, int size, u32 value)
244{ 229{
245 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 230 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
246 bridge_t *bridge = bc->base; 231 struct bridge_regs *bridge = bc->base;
247 int slot = PCI_SLOT(devfn); 232 int slot = PCI_SLOT(devfn);
248 int fn = PCI_FUNC(devfn); 233 int fn = PCI_FUNC(devfn);
249 int busno = bus->number; 234 int busno = bus->number;
@@ -251,17 +236,17 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
251 u32 cf, shift, mask, smask; 236 u32 cf, shift, mask, smask;
252 int res; 237 int res;
253 238
254 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 239 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
255 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; 240 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
256 if (get_dbe(cf, (u32 *) addr)) 241 if (get_dbe(cf, (u32 *) addr))
257 return PCIBIOS_DEVICE_NOT_FOUND; 242 return PCIBIOS_DEVICE_NOT_FOUND;
258 243
259 /* 244 /*
260 * IOC3 is fucking fucked beyond belief ... Don't even give the 245 * IOC3 is broken beyond belief ... Don't even give the
261 * generic PCI code a chance to look at it for real ... 246 * generic PCI code a chance to look at it for real ...
262 */ 247 */
263 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 248 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
264 goto oh_my_gawd; 249 goto is_ioc3;
265 250
266 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; 251 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
267 252
@@ -278,19 +263,14 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
278 263
279 return PCIBIOS_SUCCESSFUL; 264 return PCIBIOS_SUCCESSFUL;
280 265
281oh_my_gawd: 266is_ioc3:
282 267
283 /* 268 /*
284 * IOC3 is fucking fucked beyond belief ... Don't even give the 269 * IOC3 special handling
285 * generic PCI code a chance to touch the wrong register.
286 */ 270 */
287 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 271 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
288 return PCIBIOS_SUCCESSFUL; 272 return PCIBIOS_SUCCESSFUL;
289 273
290 /*
291 * IOC3 is fucking fucked beyond belief ... Don't try to access
292 * anything but 32-bit words ...
293 */
294 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 274 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
295 275
296 if (get_dbe(cf, (u32 *) addr)) 276 if (get_dbe(cf, (u32 *) addr))
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index c94a66070a60..3c177b4d0609 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -24,22 +24,11 @@
24#define MAX_PCI_BUSSES 40 24#define MAX_PCI_BUSSES 40
25 25
26/* 26/*
27 * Max #PCI devices (like scsi controllers) we handle on a bus.
28 */
29#define MAX_DEVICES_PER_PCIBUS 8
30
31/*
32 * XXX: No kmalloc available when we do our crosstalk scan, 27 * XXX: No kmalloc available when we do our crosstalk scan,
33 * we should try to move it later in the boot process. 28 * we should try to move it later in the boot process.
34 */ 29 */
35static struct bridge_controller bridges[MAX_PCI_BUSSES]; 30static struct bridge_controller bridges[MAX_PCI_BUSSES];
36 31
37/*
38 * Translate from irq to software PCI bus number and PCI slot.
39 */
40struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
41int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
42
43extern struct pci_ops bridge_pci_ops; 32extern struct pci_ops bridge_pci_ops;
44 33
45int bridge_probe(nasid_t nasid, int widget_id, int masterwid) 34int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
@@ -47,7 +36,6 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
47 unsigned long offset = NODE_OFFSET(nasid); 36 unsigned long offset = NODE_OFFSET(nasid);
48 struct bridge_controller *bc; 37 struct bridge_controller *bc;
49 static int num_bridges = 0; 38 static int num_bridges = 0;
50 bridge_t *bridge;
51 int slot; 39 int slot;
52 40
53 pci_set_flags(PCI_PROBE_ONLY); 41 pci_set_flags(PCI_PROBE_ONLY);
@@ -78,7 +66,6 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
78 bc->io.end = ~0UL; 66 bc->io.end = ~0UL;
79 bc->io.flags = IORESOURCE_IO; 67 bc->io.flags = IORESOURCE_IO;
80 68
81 bc->irq_cpu = smp_processor_id();
82 bc->widget_id = widget_id; 69 bc->widget_id = widget_id;
83 bc->nasid = nasid; 70 bc->nasid = nasid;
84 71
@@ -87,45 +74,43 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
87 /* 74 /*
88 * point to this bridge 75 * point to this bridge
89 */ 76 */
90 bridge = (bridge_t *) RAW_NODE_SWIN_BASE(nasid, widget_id); 77 bc->base = (struct bridge_regs *)RAW_NODE_SWIN_BASE(nasid, widget_id);
91 78
92 /* 79 /*
93 * Clear all pending interrupts. 80 * Clear all pending interrupts.
94 */ 81 */
95 bridge->b_int_rst_stat = BRIDGE_IRR_ALL_CLR; 82 bridge_write(bc, b_int_rst_stat, BRIDGE_IRR_ALL_CLR);
96 83
97 /* 84 /*
98 * Until otherwise set up, assume all interrupts are from slot 0 85 * Until otherwise set up, assume all interrupts are from slot 0
99 */ 86 */
100 bridge->b_int_device = 0x0; 87 bridge_write(bc, b_int_device, 0x0);
101 88
102 /* 89 /*
103 * swap pio's to pci mem and io space (big windows) 90 * swap pio's to pci mem and io space (big windows)
104 */ 91 */
105 bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP | 92 bridge_set(bc, b_wid_control, BRIDGE_CTRL_IO_SWAP |
106 BRIDGE_CTRL_MEM_SWAP; 93 BRIDGE_CTRL_MEM_SWAP);
107#ifdef CONFIG_PAGE_SIZE_4KB 94#ifdef CONFIG_PAGE_SIZE_4KB
108 bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE; 95 bridge_clr(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
109#else /* 16kB or larger */ 96#else /* 16kB or larger */
110 bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE; 97 bridge_set(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
111#endif 98#endif
112 99
113 /* 100 /*
114 * Hmm... IRIX sets additional bits in the address which 101 * Hmm... IRIX sets additional bits in the address which
115 * are documented as reserved in the bridge docs. 102 * are documented as reserved in the bridge docs.
116 */ 103 */
117 bridge->b_wid_int_upper = 0x8000 | (masterwid << 16); 104 bridge_write(bc, b_wid_int_upper, 0x8000 | (masterwid << 16));
118 bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/ 105 bridge_write(bc, b_wid_int_lower, 0x01800090); /* PI_INT_PEND_MOD off*/
119 bridge->b_dir_map = (masterwid << 20); /* DMA */ 106 bridge_write(bc, b_dir_map, (masterwid << 20)); /* DMA */
120 bridge->b_int_enable = 0; 107 bridge_write(bc, b_int_enable, 0);
121 108
122 for (slot = 0; slot < 8; slot ++) { 109 for (slot = 0; slot < 8; slot ++) {
123 bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR; 110 bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR);
124 bc->pci_int[slot] = -1; 111 bc->pci_int[slot] = -1;
125 } 112 }
126 bridge->b_wid_tflush; /* wait until Bridge PIO complete */ 113 bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */
127
128 bc->base = bridge;
129 114
130 register_pci_controller(&bc->pc); 115 register_pci_controller(&bc->pc);
131 116
@@ -168,16 +153,12 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
168 153
169 irq = bc->pci_int[slot]; 154 irq = bc->pci_int[slot];
170 if (irq == -1) { 155 if (irq == -1) {
171 irq = request_bridge_irq(bc); 156 irq = request_bridge_irq(bc, slot);
172 if (irq < 0) 157 if (irq < 0)
173 return irq; 158 return irq;
174 159
175 bc->pci_int[slot] = irq; 160 bc->pci_int[slot] = irq;
176 } 161 }
177
178 irq_to_bridge[irq] = bc;
179 irq_to_slot[irq] = slot;
180
181 dev->irq = irq; 162 dev->irq = irq;
182 163
183 return 0; 164 return 0;
@@ -206,7 +187,7 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
206static inline void pci_disable_swapping(struct pci_dev *dev) 187static inline void pci_disable_swapping(struct pci_dev *dev)
207{ 188{
208 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); 189 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
209 bridge_t *bridge = bc->base; 190 struct bridge_regs *bridge = bc->base;
210 int slot = PCI_SLOT(dev->devfn); 191 int slot = PCI_SLOT(dev->devfn);
211 192
212 /* Turn off byte swapping */ 193 /* Turn off byte swapping */
diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c
index e1fa5972a81d..648f5eb2ba68 100644
--- a/arch/mips/ralink/bootrom.c
+++ b/arch/mips/ralink/bootrom.c
@@ -35,13 +35,7 @@ static const struct file_operations bootrom_file_ops = {
35 35
36static int bootrom_setup(void) 36static int bootrom_setup(void)
37{ 37{
38 if (!debugfs_create_file("bootrom", 0444, 38 debugfs_create_file("bootrom", 0444, NULL, NULL, &bootrom_file_ops);
39 NULL, NULL, &bootrom_file_ops)) {
40 pr_err("Failed to create bootrom debugfs file\n");
41
42 return -EINVAL;
43 }
44
45 return 0; 39 return 0;
46} 40}
47 41
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile
index 73502fda13ee..27c14ede191e 100644
--- a/arch/mips/sgi-ip27/Makefile
+++ b/arch/mips/sgi-ip27/Makefile
@@ -3,10 +3,9 @@
3# Makefile for the IP27 specific kernel interface routines under Linux. 3# Makefile for the IP27 specific kernel interface routines under Linux.
4# 4#
5 5
6obj-y := ip27-berr.o ip27-irq.o ip27-irqno.o ip27-init.o ip27-klconfig.o \ 6obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o \
7 ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \ 7 ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \
8 ip27-hubio.o ip27-xtalk.o 8 ip27-hubio.o ip27-xtalk.o
9 9
10obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o 10obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o
11obj-$(CONFIG_PCI) += ip27-irq-pci.o
12obj-$(CONFIG_SMP) += ip27-smp.o 11obj-$(CONFIG_SMP) += ip27-smp.o
diff --git a/arch/mips/sgi-ip27/ip27-hubio.c b/arch/mips/sgi-ip27/ip27-hubio.c
index 2abe016a0ffc..68fb0cb89d9d 100644
--- a/arch/mips/sgi-ip27/ip27-hubio.c
+++ b/arch/mips/sgi-ip27/ip27-hubio.c
@@ -63,7 +63,7 @@ unsigned long hub_pio_map(cnodeid_t cnode, xwidgetnum_t widget,
63 * after we write it. 63 * after we write it.
64 */ 64 */
65 IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr); 65 IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr);
66 (void) HUB_L(IIO_ITTE_GET(nasid, i)); 66 __raw_readq(IIO_ITTE_GET(nasid, i));
67 67
68 return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE); 68 return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE);
69 } 69 }
@@ -135,7 +135,7 @@ static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
135 **/ 135 **/
136static void hub_set_piomode(nasid_t nasid) 136static void hub_set_piomode(nasid_t nasid)
137{ 137{
138 hubreg_t ii_iowa; 138 u64 ii_iowa;
139 hubii_wcr_t ii_wcr; 139 hubii_wcr_t ii_wcr;
140 unsigned i; 140 unsigned i;
141 141
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index e501c43c02db..6074efeff894 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -52,13 +52,10 @@ EXPORT_SYMBOL_GPL(sn_cpu_info);
52 52
53extern void pcibr_setup(cnodeid_t); 53extern void pcibr_setup(cnodeid_t);
54 54
55extern void xtalk_probe_node(cnodeid_t nid);
56
57static void per_hub_init(cnodeid_t cnode) 55static void per_hub_init(cnodeid_t cnode)
58{ 56{
59 struct hub_data *hub = hub_data(cnode); 57 struct hub_data *hub = hub_data(cnode);
60 nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); 58 nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
61 int i;
62 59
63 cpumask_set_cpu(smp_processor_id(), &hub->h_cpus); 60 cpumask_set_cpu(smp_processor_id(), &hub->h_cpus);
64 61
@@ -71,7 +68,6 @@ static void per_hub_init(cnodeid_t cnode)
71 REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); 68 REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
72 69
73 hub_rtc_init(cnode); 70 hub_rtc_init(cnode);
74 xtalk_probe_node(cnode);
75 71
76#ifdef CONFIG_REPLICATE_EXHANDLERS 72#ifdef CONFIG_REPLICATE_EXHANDLERS
77 /* 73 /*
@@ -90,24 +86,6 @@ static void per_hub_init(cnodeid_t cnode)
90 __flush_cache_all(); 86 __flush_cache_all();
91 } 87 }
92#endif 88#endif
93
94 /*
95 * Some interrupts are reserved by hardware or by software convention.
96 * Mark these as reserved right away so they won't be used accidentally
97 * later.
98 */
99 for (i = 0; i <= BASE_PCI_IRQ; i++) {
100 __set_bit(i, hub->irq_alloc_mask);
101 LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
102 }
103
104 __set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
105 LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
106
107 for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
108 __set_bit(i, hub->irq_alloc_mask);
109 LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
110 }
111} 89}
112 90
113void per_cpu_init(void) 91void per_cpu_init(void)
@@ -116,8 +94,6 @@ void per_cpu_init(void)
116 int slice = LOCAL_HUB_L(PI_CPU_NUM); 94 int slice = LOCAL_HUB_L(PI_CPU_NUM);
117 cnodeid_t cnode = get_compact_nodeid(); 95 cnodeid_t cnode = get_compact_nodeid();
118 struct hub_data *hub = hub_data(cnode); 96 struct hub_data *hub = hub_data(cnode);
119 struct slice_data *si = hub->slice + slice;
120 int i;
121 97
122 if (test_and_set_bit(slice, &hub->slice_map)) 98 if (test_and_set_bit(slice, &hub->slice_map))
123 return; 99 return;
@@ -126,22 +102,14 @@ void per_cpu_init(void)
126 102
127 per_hub_init(cnode); 103 per_hub_init(cnode);
128 104
129 for (i = 0; i < LEVELS_PER_SLICE; i++)
130 si->level_to_irq[i] = -1;
131
132 /*
133 * We use this so we can find the local hub's data as fast as only
134 * possible.
135 */
136 cpu_data[cpu].data = si;
137
138 cpu_time_init(); 105 cpu_time_init();
139 install_ipi(); 106 install_ipi();
140 107
141 /* Install our NMI handler if symmon hasn't installed one. */ 108 /* Install our NMI handler if symmon hasn't installed one. */
142 install_cpu_nmi_handler(cputoslice(cpu)); 109 install_cpu_nmi_handler(cputoslice(cpu));
143 110
144 set_c0_status(SRB_DEV0 | SRB_DEV1); 111 enable_percpu_irq(IP27_HUB_PEND0_IRQ, IRQ_TYPE_NONE);
112 enable_percpu_irq(IP27_HUB_PEND1_IRQ, IRQ_TYPE_NONE);
145} 113}
146 114
147/* 115/*
@@ -177,7 +145,7 @@ extern void ip27_reboot_setup(void);
177 145
178void __init plat_mem_setup(void) 146void __init plat_mem_setup(void)
179{ 147{
180 hubreg_t p, e, n_mode; 148 u64 p, e, n_mode;
181 nasid_t nid; 149 nasid_t nid;
182 150
183 ip27_reboot_setup(); 151 ip27_reboot_setup();
@@ -215,7 +183,6 @@ void __init plat_mem_setup(void)
215#endif 183#endif
216 184
217 ioc3_eth_init(); 185 ioc3_eth_init();
218 per_cpu_init();
219 186
220 set_io_port_base(IO_BASE); 187 set_io_port_base(IO_BASE);
221} 188}
diff --git a/arch/mips/sgi-ip27/ip27-irq-pci.c b/arch/mips/sgi-ip27/ip27-irq-pci.c
deleted file mode 100644
index cd449e90b917..000000000000
--- a/arch/mips/sgi-ip27/ip27-irq-pci.c
+++ /dev/null
@@ -1,266 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
4 *
5 * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
6 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
7 * Copyright (C) 1999 - 2001 Kanoj Sarcar
8 */
9
10#undef DEBUG
11
12#include <linux/irq.h>
13#include <linux/errno.h>
14#include <linux/signal.h>
15#include <linux/sched.h>
16#include <linux/types.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/timex.h>
20#include <linux/smp.h>
21#include <linux/random.h>
22#include <linux/kernel.h>
23#include <linux/kernel_stat.h>
24#include <linux/delay.h>
25#include <linux/bitops.h>
26
27#include <asm/bootinfo.h>
28#include <asm/io.h>
29#include <asm/mipsregs.h>
30
31#include <asm/processor.h>
32#include <asm/pci/bridge.h>
33#include <asm/sn/addrs.h>
34#include <asm/sn/agent.h>
35#include <asm/sn/arch.h>
36#include <asm/sn/hub.h>
37#include <asm/sn/intr.h>
38
39/*
40 * Linux has a controller-independent x86 interrupt architecture.
41 * every controller has a 'controller-template', that is used
42 * by the main code to do the right thing. Each driver-visible
43 * interrupt source is transparently wired to the appropriate
44 * controller. Thus drivers need not be aware of the
45 * interrupt-controller.
46 *
47 * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
48 * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
49 * (IO-APICs assumed to be messaging to Pentium local-APICs)
50 *
51 * the code is designed to be easily extended with new/different
52 * interrupt controllers, without having to do assembly magic.
53 */
54
55extern struct bridge_controller *irq_to_bridge[];
56extern int irq_to_slot[];
57
58/*
59 * use these macros to get the encoded nasid and widget id
60 * from the irq value
61 */
62#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)]
63#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i]
64
65static inline int alloc_level(int cpu, int irq)
66{
67 struct hub_data *hub = hub_data(cpu_to_node(cpu));
68 struct slice_data *si = cpu_data[cpu].data;
69 int level;
70
71 level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
72 if (level >= LEVELS_PER_SLICE)
73 panic("Cpu %d flooded with devices", cpu);
74
75 __set_bit(level, hub->irq_alloc_mask);
76 si->level_to_irq[level] = irq;
77
78 return level;
79}
80
81static inline int find_level(cpuid_t *cpunum, int irq)
82{
83 int cpu, i;
84
85 for_each_online_cpu(cpu) {
86 struct slice_data *si = cpu_data[cpu].data;
87
88 for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
89 if (si->level_to_irq[i] == irq) {
90 *cpunum = cpu;
91
92 return i;
93 }
94 }
95
96 panic("Could not identify cpu/level for irq %d", irq);
97}
98
99static int intr_connect_level(int cpu, int bit)
100{
101 nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
102 struct slice_data *si = cpu_data[cpu].data;
103
104 set_bit(bit, si->irq_enable_mask);
105
106 if (!cputoslice(cpu)) {
107 REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
108 REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
109 } else {
110 REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
111 REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
112 }
113
114 return 0;
115}
116
117static int intr_disconnect_level(int cpu, int bit)
118{
119 nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
120 struct slice_data *si = cpu_data[cpu].data;
121
122 clear_bit(bit, si->irq_enable_mask);
123
124 if (!cputoslice(cpu)) {
125 REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
126 REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
127 } else {
128 REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
129 REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
130 }
131
132 return 0;
133}
134
135/* Startup one of the (PCI ...) IRQs routes over a bridge. */
136static unsigned int startup_bridge_irq(struct irq_data *d)
137{
138 struct bridge_controller *bc;
139 bridgereg_t device;
140 bridge_t *bridge;
141 int pin, swlevel;
142 cpuid_t cpu;
143
144 pin = SLOT_FROM_PCI_IRQ(d->irq);
145 bc = IRQ_TO_BRIDGE(d->irq);
146 bridge = bc->base;
147
148 pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin);
149 /*
150 * "map" irq to a swlevel greater than 6 since the first 6 bits
151 * of INT_PEND0 are taken
152 */
153 swlevel = find_level(&cpu, d->irq);
154 bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
155 bridge->b_int_enable |= (1 << pin);
156 bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */
157
158 /*
159 * Enable sending of an interrupt clear packt to the hub on a high to
160 * low transition of the interrupt pin.
161 *
162 * IRIX sets additional bits in the address which are documented as
163 * reserved in the bridge docs.
164 */
165 bridge->b_int_mode |= (1UL << pin);
166
167 /*
168 * We assume the bridge to have a 1:1 mapping between devices
169 * (slots) and intr pins.
170 */
171 device = bridge->b_int_device;
172 device &= ~(7 << (pin*3));
173 device |= (pin << (pin*3));
174 bridge->b_int_device = device;
175
176 bridge->b_wid_tflush;
177
178 intr_connect_level(cpu, swlevel);
179
180 return 0; /* Never anything pending. */
181}
182
183/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */
184static void shutdown_bridge_irq(struct irq_data *d)
185{
186 struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
187 bridge_t *bridge = bc->base;
188 int pin, swlevel;
189 cpuid_t cpu;
190
191 pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
192 pin = SLOT_FROM_PCI_IRQ(d->irq);
193
194 /*
195 * map irq to a swlevel greater than 6 since the first 6 bits
196 * of INT_PEND0 are taken
197 */
198 swlevel = find_level(&cpu, d->irq);
199 intr_disconnect_level(cpu, swlevel);
200
201 bridge->b_int_enable &= ~(1 << pin);
202 bridge->b_wid_tflush;
203}
204
205static inline void enable_bridge_irq(struct irq_data *d)
206{
207 cpuid_t cpu;
208 int swlevel;
209
210 swlevel = find_level(&cpu, d->irq); /* Criminal offence */
211 intr_connect_level(cpu, swlevel);
212}
213
214static inline void disable_bridge_irq(struct irq_data *d)
215{
216 cpuid_t cpu;
217 int swlevel;
218
219 swlevel = find_level(&cpu, d->irq); /* Criminal offence */
220 intr_disconnect_level(cpu, swlevel);
221}
222
223static struct irq_chip bridge_irq_type = {
224 .name = "bridge",
225 .irq_startup = startup_bridge_irq,
226 .irq_shutdown = shutdown_bridge_irq,
227 .irq_mask = disable_bridge_irq,
228 .irq_unmask = enable_bridge_irq,
229};
230
231void register_bridge_irq(unsigned int irq)
232{
233 irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
234}
235
236int request_bridge_irq(struct bridge_controller *bc)
237{
238 int irq = allocate_irqno();
239 int swlevel, cpu;
240 nasid_t nasid;
241
242 if (irq < 0)
243 return irq;
244
245 /*
246 * "map" irq to a swlevel greater than 6 since the first 6 bits
247 * of INT_PEND0 are taken
248 */
249 cpu = bc->irq_cpu;
250 swlevel = alloc_level(cpu, irq);
251 if (unlikely(swlevel < 0)) {
252 free_irqno(irq);
253
254 return -EAGAIN;
255 }
256
257 /* Make sure it's not already pending when we connect it. */
258 nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
259 REMOTE_HUB_CLR_INTR(nasid, swlevel);
260
261 intr_connect_level(cpu, swlevel);
262
263 register_bridge_irq(irq);
264
265 return irq;
266}
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 0dde6164a06f..710a59764b01 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -7,67 +7,234 @@
7 * Copyright (C) 1999 - 2001 Kanoj Sarcar 7 * Copyright (C) 1999 - 2001 Kanoj Sarcar
8 */ 8 */
9 9
10#undef DEBUG
11
12#include <linux/init.h>
13#include <linux/irq.h>
14#include <linux/errno.h>
15#include <linux/signal.h>
16#include <linux/sched.h>
17#include <linux/types.h>
18#include <linux/interrupt.h> 10#include <linux/interrupt.h>
11#include <linux/irq.h>
19#include <linux/ioport.h> 12#include <linux/ioport.h>
20#include <linux/timex.h>
21#include <linux/smp.h>
22#include <linux/random.h>
23#include <linux/kernel.h> 13#include <linux/kernel.h>
24#include <linux/kernel_stat.h>
25#include <linux/delay.h>
26#include <linux/bitops.h> 14#include <linux/bitops.h>
27 15
28#include <asm/bootinfo.h>
29#include <asm/io.h> 16#include <asm/io.h>
30#include <asm/mipsregs.h> 17#include <asm/irq_cpu.h>
31 18#include <asm/pci/bridge.h>
32#include <asm/processor.h>
33#include <asm/sn/addrs.h> 19#include <asm/sn/addrs.h>
34#include <asm/sn/agent.h> 20#include <asm/sn/agent.h>
35#include <asm/sn/arch.h> 21#include <asm/sn/arch.h>
36#include <asm/sn/hub.h> 22#include <asm/sn/hub.h>
37#include <asm/sn/intr.h> 23#include <asm/sn/intr.h>
38 24
39/* 25struct hub_irq_data {
40 * Linux has a controller-independent x86 interrupt architecture. 26 struct bridge_controller *bc;
41 * every controller has a 'controller-template', that is used 27 u64 *irq_mask[2];
42 * by the main code to do the right thing. Each driver-visible 28 cpuid_t cpu;
43 * interrupt source is transparently wired to the appropriate 29 int bit;
44 * controller. Thus drivers need not be aware of the 30 int pin;
45 * interrupt-controller. 31};
46 *
47 * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
48 * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
49 * (IO-APICs assumed to be messaging to Pentium local-APICs)
50 *
51 * the code is designed to be easily extended with new/different
52 * interrupt controllers, without having to do assembly magic.
53 */
54 32
55extern asmlinkage void ip27_irq(void); 33static DECLARE_BITMAP(hub_irq_map, IP27_HUB_IRQ_COUNT);
56 34
57/* 35static DEFINE_PER_CPU(unsigned long [2], irq_enable_mask);
58 * Find first bit set 36
59 */ 37static inline int alloc_level(void)
60static int ms1bit(unsigned long x) 38{
39 int level;
40
41again:
42 level = find_first_zero_bit(hub_irq_map, IP27_HUB_IRQ_COUNT);
43 if (level >= IP27_HUB_IRQ_COUNT)
44 return -ENOSPC;
45
46 if (test_and_set_bit(level, hub_irq_map))
47 goto again;
48
49 return level;
50}
51
52static void enable_hub_irq(struct irq_data *d)
53{
54 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
55 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu);
56
57 set_bit(hd->bit, mask);
58 __raw_writeq(mask[0], hd->irq_mask[0]);
59 __raw_writeq(mask[1], hd->irq_mask[1]);
60}
61
62static void disable_hub_irq(struct irq_data *d)
63{
64 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
65 unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu);
66
67 clear_bit(hd->bit, mask);
68 __raw_writeq(mask[0], hd->irq_mask[0]);
69 __raw_writeq(mask[1], hd->irq_mask[1]);
70}
71
72static unsigned int startup_bridge_irq(struct irq_data *d)
73{
74 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
75 struct bridge_controller *bc;
76 nasid_t nasid;
77 u32 device;
78 int pin;
79
80 if (!hd)
81 return -EINVAL;
82
83 pin = hd->pin;
84 bc = hd->bc;
85
86 nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(hd->cpu));
87 bridge_write(bc, b_int_addr[pin].addr,
88 (0x20000 | hd->bit | (nasid << 8)));
89 bridge_set(bc, b_int_enable, (1 << pin));
90 bridge_set(bc, b_int_enable, 0x7ffffe00); /* more stuff in int_enable */
91
92 /*
93 * Enable sending of an interrupt clear packt to the hub on a high to
94 * low transition of the interrupt pin.
95 *
96 * IRIX sets additional bits in the address which are documented as
97 * reserved in the bridge docs.
98 */
99 bridge_set(bc, b_int_mode, (1UL << pin));
100
101 /*
102 * We assume the bridge to have a 1:1 mapping between devices
103 * (slots) and intr pins.
104 */
105 device = bridge_read(bc, b_int_device);
106 device &= ~(7 << (pin*3));
107 device |= (pin << (pin*3));
108 bridge_write(bc, b_int_device, device);
109
110 bridge_read(bc, b_wid_tflush);
111
112 enable_hub_irq(d);
113
114 return 0; /* Never anything pending. */
115}
116
117static void shutdown_bridge_irq(struct irq_data *d)
118{
119 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
120 struct bridge_controller *bc;
121 int pin = hd->pin;
122
123 if (!hd)
124 return;
125
126 disable_hub_irq(d);
127
128 bc = hd->bc;
129 bridge_clr(bc, b_int_enable, (1 << pin));
130 bridge_read(bc, b_wid_tflush);
131}
132
133static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask)
134{
135 nasid_t nasid;
136 int cpu;
137
138 cpu = cpumask_first_and(mask, cpu_online_mask);
139 nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
140 hd->cpu = cpu;
141 if (!cputoslice(cpu)) {
142 hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_A);
143 hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_A);
144 } else {
145 hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_B);
146 hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_B);
147 }
148
149 /* Make sure it's not already pending when we connect it. */
150 REMOTE_HUB_CLR_INTR(nasid, hd->bit);
151}
152
153static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask,
154 bool force)
155{
156 struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
157
158 if (!hd)
159 return -EINVAL;
160
161 if (irqd_is_started(d))
162 disable_hub_irq(d);
163
164 setup_hub_mask(hd, mask);
165
166 if (irqd_is_started(d))
167 startup_bridge_irq(d);
168
169 irq_data_update_effective_affinity(d, cpumask_of(hd->cpu));
170
171 return 0;
172}
173
174static struct irq_chip hub_irq_type = {
175 .name = "HUB",
176 .irq_startup = startup_bridge_irq,
177 .irq_shutdown = shutdown_bridge_irq,
178 .irq_mask = disable_hub_irq,
179 .irq_unmask = enable_hub_irq,
180 .irq_set_affinity = set_affinity_hub_irq,
181};
182
183int request_bridge_irq(struct bridge_controller *bc, int pin)
61{ 184{
62 int b = 0, s; 185 struct hub_irq_data *hd;
186 struct hub_data *hub;
187 struct irq_desc *desc;
188 int swlevel;
189 int irq;
190
191 hd = kzalloc(sizeof(*hd), GFP_KERNEL);
192 if (!hd)
193 return -ENOMEM;
194
195 swlevel = alloc_level();
196 if (unlikely(swlevel < 0)) {
197 kfree(hd);
198 return -EAGAIN;
199 }
200 irq = swlevel + IP27_HUB_IRQ_BASE;
201
202 hd->bc = bc;
203 hd->bit = swlevel;
204 hd->pin = pin;
205 irq_set_chip_data(irq, hd);
206
207 /* use CPU connected to nearest hub */
208 hub = hub_data(NASID_TO_COMPACT_NODEID(bc->nasid));
209 setup_hub_mask(hd, &hub->h_cpus);
63 210
64 s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s; 211 desc = irq_to_desc(irq);
65 s = 8; if (x >> 8 == 0) s = 0; b += s; x >>= s; 212 desc->irq_common_data.node = bc->nasid;
66 s = 4; if (x >> 4 == 0) s = 0; b += s; x >>= s; 213 cpumask_copy(desc->irq_common_data.affinity, &hub->h_cpus);
67 s = 2; if (x >> 2 == 0) s = 0; b += s; x >>= s;
68 s = 1; if (x >> 1 == 0) s = 0; b += s;
69 214
70 return b; 215 return irq;
216}
217
218void ip27_hub_irq_init(void)
219{
220 int i;
221
222 for (i = IP27_HUB_IRQ_BASE;
223 i < (IP27_HUB_IRQ_BASE + IP27_HUB_IRQ_COUNT); i++)
224 irq_set_chip_and_handler(i, &hub_irq_type, handle_level_irq);
225
226 /*
227 * Some interrupts are reserved by hardware or by software convention.
228 * Mark these as reserved right away so they won't be used accidentally
229 * later.
230 */
231 for (i = 0; i <= BASE_PCI_IRQ; i++)
232 set_bit(i, hub_irq_map);
233
234 set_bit(IP_PEND0_6_63, hub_irq_map);
235
236 for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++)
237 set_bit(i, hub_irq_map);
71} 238}
72 239
73/* 240/*
@@ -82,23 +249,19 @@ static int ms1bit(unsigned long x)
82 * Kanoj 05.13.00 249 * Kanoj 05.13.00
83 */ 250 */
84 251
85static void ip27_do_irq_mask0(void) 252static void ip27_do_irq_mask0(struct irq_desc *desc)
86{ 253{
87 int irq, swlevel;
88 hubreg_t pend0, mask0;
89 cpuid_t cpu = smp_processor_id(); 254 cpuid_t cpu = smp_processor_id();
90 int pi_int_mask0 = 255 unsigned long *mask = per_cpu(irq_enable_mask, cpu);
91 (cputoslice(cpu) == 0) ? PI_INT_MASK0_A : PI_INT_MASK0_B; 256 u64 pend0;
92 257
93 /* copied from Irix intpend0() */ 258 /* copied from Irix intpend0() */
94 pend0 = LOCAL_HUB_L(PI_INT_PEND0); 259 pend0 = LOCAL_HUB_L(PI_INT_PEND0);
95 mask0 = LOCAL_HUB_L(pi_int_mask0);
96 260
97 pend0 &= mask0; /* Pick intrs we should look at */ 261 pend0 &= mask[0]; /* Pick intrs we should look at */
98 if (!pend0) 262 if (!pend0)
99 return; 263 return;
100 264
101 swlevel = ms1bit(pend0);
102#ifdef CONFIG_SMP 265#ifdef CONFIG_SMP
103 if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) { 266 if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) {
104 LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ); 267 LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
@@ -108,106 +271,66 @@ static void ip27_do_irq_mask0(void)
108 scheduler_ipi(); 271 scheduler_ipi();
109 } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) { 272 } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) {
110 LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ); 273 LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
111 irq_enter();
112 generic_smp_call_function_interrupt(); 274 generic_smp_call_function_interrupt();
113 irq_exit();
114 } else if (pend0 & (1UL << CPU_CALL_B_IRQ)) { 275 } else if (pend0 & (1UL << CPU_CALL_B_IRQ)) {
115 LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ); 276 LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
116 irq_enter();
117 generic_smp_call_function_interrupt(); 277 generic_smp_call_function_interrupt();
118 irq_exit();
119 } else 278 } else
120#endif 279#endif
121 { 280 generic_handle_irq(__ffs(pend0) + IP27_HUB_IRQ_BASE);
122 /* "map" swlevel to irq */
123 struct slice_data *si = cpu_data[cpu].data;
124
125 irq = si->level_to_irq[swlevel];
126 do_IRQ(irq);
127 }
128 281
129 LOCAL_HUB_L(PI_INT_PEND0); 282 LOCAL_HUB_L(PI_INT_PEND0);
130} 283}
131 284
132static void ip27_do_irq_mask1(void) 285static void ip27_do_irq_mask1(struct irq_desc *desc)
133{ 286{
134 int irq, swlevel;
135 hubreg_t pend1, mask1;
136 cpuid_t cpu = smp_processor_id(); 287 cpuid_t cpu = smp_processor_id();
137 int pi_int_mask1 = (cputoslice(cpu) == 0) ? PI_INT_MASK1_A : PI_INT_MASK1_B; 288 unsigned long *mask = per_cpu(irq_enable_mask, cpu);
138 struct slice_data *si = cpu_data[cpu].data; 289 u64 pend1;
139 290
140 /* copied from Irix intpend0() */ 291 /* copied from Irix intpend0() */
141 pend1 = LOCAL_HUB_L(PI_INT_PEND1); 292 pend1 = LOCAL_HUB_L(PI_INT_PEND1);
142 mask1 = LOCAL_HUB_L(pi_int_mask1);
143 293
144 pend1 &= mask1; /* Pick intrs we should look at */ 294 pend1 &= mask[1]; /* Pick intrs we should look at */
145 if (!pend1) 295 if (!pend1)
146 return; 296 return;
147 297
148 swlevel = ms1bit(pend1); 298 generic_handle_irq(__ffs(pend1) + IP27_HUB_IRQ_BASE + 64);
149 /* "map" swlevel to irq */
150 irq = si->level_to_irq[swlevel];
151 LOCAL_HUB_CLR_INTR(swlevel);
152 do_IRQ(irq);
153 299
154 LOCAL_HUB_L(PI_INT_PEND1); 300 LOCAL_HUB_L(PI_INT_PEND1);
155} 301}
156 302
157static void ip27_prof_timer(void)
158{
159 panic("CPU %d got a profiling interrupt", smp_processor_id());
160}
161
162static void ip27_hub_error(void)
163{
164 panic("CPU %d got a hub error interrupt", smp_processor_id());
165}
166
167asmlinkage void plat_irq_dispatch(void)
168{
169 unsigned long pending = read_c0_cause() & read_c0_status();
170 extern unsigned int rt_timer_irq;
171
172 if (pending & CAUSEF_IP4)
173 do_IRQ(rt_timer_irq);
174 else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */
175 ip27_do_irq_mask0();
176 else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */
177 ip27_do_irq_mask1();
178 else if (pending & CAUSEF_IP5)
179 ip27_prof_timer();
180 else if (pending & CAUSEF_IP6)
181 ip27_hub_error();
182}
183
184void __init arch_init_irq(void)
185{
186}
187
188void install_ipi(void) 303void install_ipi(void)
189{ 304{
190 int slice = LOCAL_HUB_L(PI_CPU_NUM);
191 int cpu = smp_processor_id(); 305 int cpu = smp_processor_id();
192 struct slice_data *si = cpu_data[cpu].data; 306 unsigned long *mask = per_cpu(irq_enable_mask, cpu);
193 struct hub_data *hub = hub_data(cpu_to_node(cpu)); 307 int slice = LOCAL_HUB_L(PI_CPU_NUM);
194 int resched, call; 308 int resched, call;
195 309
196 resched = CPU_RESCHED_A_IRQ + slice; 310 resched = CPU_RESCHED_A_IRQ + slice;
197 __set_bit(resched, hub->irq_alloc_mask); 311 set_bit(resched, mask);
198 __set_bit(resched, si->irq_enable_mask);
199 LOCAL_HUB_CLR_INTR(resched); 312 LOCAL_HUB_CLR_INTR(resched);
200 313
201 call = CPU_CALL_A_IRQ + slice; 314 call = CPU_CALL_A_IRQ + slice;
202 __set_bit(call, hub->irq_alloc_mask); 315 set_bit(call, mask);
203 __set_bit(call, si->irq_enable_mask);
204 LOCAL_HUB_CLR_INTR(call); 316 LOCAL_HUB_CLR_INTR(call);
205 317
206 if (slice == 0) { 318 if (slice == 0) {
207 LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]); 319 LOCAL_HUB_S(PI_INT_MASK0_A, mask[0]);
208 LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]); 320 LOCAL_HUB_S(PI_INT_MASK1_A, mask[1]);
209 } else { 321 } else {
210 LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]); 322 LOCAL_HUB_S(PI_INT_MASK0_B, mask[0]);
211 LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]); 323 LOCAL_HUB_S(PI_INT_MASK1_B, mask[1]);
212 } 324 }
213} 325}
326
327void __init arch_init_irq(void)
328{
329 mips_cpu_irq_init();
330 ip27_hub_irq_init();
331
332 irq_set_percpu_devid(IP27_HUB_PEND0_IRQ);
333 irq_set_chained_handler(IP27_HUB_PEND0_IRQ, ip27_do_irq_mask0);
334 irq_set_percpu_devid(IP27_HUB_PEND1_IRQ);
335 irq_set_chained_handler(IP27_HUB_PEND1_IRQ, ip27_do_irq_mask1);
336}
diff --git a/arch/mips/sgi-ip27/ip27-irqno.c b/arch/mips/sgi-ip27/ip27-irqno.c
deleted file mode 100644
index 957ab58e1c00..000000000000
--- a/arch/mips/sgi-ip27/ip27-irqno.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 */
6#include <linux/init.h>
7#include <linux/irq.h>
8#include <linux/types.h>
9
10#include <asm/barrier.h>
11
12static DECLARE_BITMAP(irq_map, NR_IRQS);
13
14int allocate_irqno(void)
15{
16 int irq;
17
18again:
19 irq = find_first_zero_bit(irq_map, NR_IRQS);
20
21 if (irq >= NR_IRQS)
22 return -ENOSPC;
23
24 if (test_and_set_bit(irq, irq_map))
25 goto again;
26
27 return irq;
28}
29
30/*
31 * Allocate the 16 legacy interrupts for i8259 devices. This happens early
32 * in the kernel initialization so treating allocation failure as BUG() is
33 * ok.
34 */
35void __init alloc_legacy_irqno(void)
36{
37 int i;
38
39 for (i = 0; i <= 16; i++)
40 BUG_ON(test_and_set_bit(i, irq_map));
41}
42
43void free_irqno(unsigned int irq)
44{
45 smp_mb__before_atomic();
46 clear_bit(irq, irq_map);
47 smp_mb__after_atomic();
48}
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index 813d13f92957..fb077a947575 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -44,7 +44,7 @@ static int is_fine_dirmode(void)
44 return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE; 44 return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE;
45} 45}
46 46
47static hubreg_t get_region(cnodeid_t cnode) 47static u64 get_region(cnodeid_t cnode)
48{ 48{
49 if (fine_mode) 49 if (fine_mode)
50 return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT; 50 return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
@@ -52,9 +52,9 @@ static hubreg_t get_region(cnodeid_t cnode)
52 return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT; 52 return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
53} 53}
54 54
55static hubreg_t region_mask; 55static u64 region_mask;
56 56
57static void gen_region_mask(hubreg_t *region_mask) 57static void gen_region_mask(u64 *region_mask)
58{ 58{
59 cnodeid_t cnode; 59 cnodeid_t cnode;
60 60
@@ -154,11 +154,11 @@ static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
154 } 154 }
155 155
156 if (router_a == NULL) { 156 if (router_a == NULL) {
157 printk("node_distance: router_a NULL\n"); 157 pr_info("node_distance: router_a NULL\n");
158 return -1; 158 return -1;
159 } 159 }
160 if (router_b == NULL) { 160 if (router_b == NULL) {
161 printk("node_distance: router_b NULL\n"); 161 pr_info("node_distance: router_b NULL\n");
162 return -1; 162 return -1;
163 } 163 }
164 164
@@ -203,17 +203,17 @@ static void __init dump_topology(void)
203 klrou_t *router; 203 klrou_t *router;
204 cnodeid_t row, col; 204 cnodeid_t row, col;
205 205
206 printk("************** Topology ********************\n"); 206 pr_info("************** Topology ********************\n");
207 207
208 printk(" "); 208 pr_info(" ");
209 for_each_online_node(col) 209 for_each_online_node(col)
210 printk("%02d ", col); 210 pr_cont("%02d ", col);
211 printk("\n"); 211 pr_cont("\n");
212 for_each_online_node(row) { 212 for_each_online_node(row) {
213 printk("%02d ", row); 213 pr_info("%02d ", row);
214 for_each_online_node(col) 214 for_each_online_node(col)
215 printk("%2d ", node_distance(row, col)); 215 pr_cont("%2d ", node_distance(row, col));
216 printk("\n"); 216 pr_cont("\n");
217 } 217 }
218 218
219 for_each_online_node(cnode) { 219 for_each_online_node(cnode) {
@@ -230,7 +230,7 @@ static void __init dump_topology(void)
230 do { 230 do {
231 if (brd->brd_flags & DUPLICATE_BOARD) 231 if (brd->brd_flags & DUPLICATE_BOARD)
232 continue; 232 continue;
233 printk("Router %d:", router_num); 233 pr_cont("Router %d:", router_num);
234 router_num++; 234 router_num++;
235 235
236 router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); 236 router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
@@ -244,11 +244,11 @@ static void __init dump_topology(void)
244 router->rou_port[port].port_offset); 244 router->rou_port[port].port_offset);
245 245
246 if (dest_brd->brd_type == KLTYPE_IP27) 246 if (dest_brd->brd_type == KLTYPE_IP27)
247 printk(" %d", dest_brd->brd_nasid); 247 pr_cont(" %d", dest_brd->brd_nasid);
248 if (dest_brd->brd_type == KLTYPE_ROUTER) 248 if (dest_brd->brd_type == KLTYPE_ROUTER)
249 printk(" r"); 249 pr_cont(" r");
250 } 250 }
251 printk("\n"); 251 pr_cont("\n");
252 252
253 } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); 253 } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
254 } 254 }
@@ -373,7 +373,7 @@ static void __init szmem(void)
373 373
374 if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > 374 if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
375 (slot0sz << PAGE_SHIFT)) { 375 (slot0sz << PAGE_SHIFT)) {
376 printk("Ignoring slot %d onwards on node %d\n", 376 pr_info("Ignoring slot %d onwards on node %d\n",
377 slot, node); 377 slot, node);
378 slot = MAX_MEM_SLOTS; 378 slot = MAX_MEM_SLOTS;
379 continue; 379 continue;
diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
index 8ac2bfa35fb6..3aae388561d9 100644
--- a/arch/mips/sgi-ip27/ip27-nmi.c
+++ b/arch/mips/sgi-ip27/ip27-nmi.c
@@ -62,75 +62,75 @@ void nmi_cpu_eframe_save(nasid_t nasid, int slice)
62 (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + 62 (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
63 slice * IP27_NMI_KREGS_CPU_SIZE); 63 slice * IP27_NMI_KREGS_CPU_SIZE);
64 64
65 printk("NMI nasid %d: slice %d\n", nasid, slice); 65 pr_emerg("NMI nasid %d: slice %d\n", nasid, slice);
66 66
67 /* 67 /*
68 * Saved main processor registers 68 * Saved main processor registers
69 */ 69 */
70 for (i = 0; i < 32; ) { 70 for (i = 0; i < 32; ) {
71 if ((i % 4) == 0) 71 if ((i % 4) == 0)
72 printk("$%2d :", i); 72 pr_emerg("$%2d :", i);
73 printk(" %016lx", nr->gpr[i]); 73 pr_cont(" %016lx", nr->gpr[i]);
74 74
75 i++; 75 i++;
76 if ((i % 4) == 0) 76 if ((i % 4) == 0)
77 printk("\n"); 77 pr_cont("\n");
78 } 78 }
79 79
80 printk("Hi : (value lost)\n"); 80 pr_emerg("Hi : (value lost)\n");
81 printk("Lo : (value lost)\n"); 81 pr_emerg("Lo : (value lost)\n");
82 82
83 /* 83 /*
84 * Saved cp0 registers 84 * Saved cp0 registers
85 */ 85 */
86 printk("epc : %016lx %pS\n", nr->epc, (void *) nr->epc); 86 pr_emerg("epc : %016lx %pS\n", nr->epc, (void *)nr->epc);
87 printk("%s\n", print_tainted()); 87 pr_emerg("%s\n", print_tainted());
88 printk("ErrEPC: %016lx %pS\n", nr->error_epc, (void *) nr->error_epc); 88 pr_emerg("ErrEPC: %016lx %pS\n", nr->error_epc, (void *)nr->error_epc);
89 printk("ra : %016lx %pS\n", nr->gpr[31], (void *) nr->gpr[31]); 89 pr_emerg("ra : %016lx %pS\n", nr->gpr[31], (void *)nr->gpr[31]);
90 printk("Status: %08lx ", nr->sr); 90 pr_emerg("Status: %08lx ", nr->sr);
91 91
92 if (nr->sr & ST0_KX) 92 if (nr->sr & ST0_KX)
93 printk("KX "); 93 pr_cont("KX ");
94 if (nr->sr & ST0_SX) 94 if (nr->sr & ST0_SX)
95 printk("SX "); 95 pr_cont("SX ");
96 if (nr->sr & ST0_UX) 96 if (nr->sr & ST0_UX)
97 printk("UX "); 97 pr_cont("UX ");
98 98
99 switch (nr->sr & ST0_KSU) { 99 switch (nr->sr & ST0_KSU) {
100 case KSU_USER: 100 case KSU_USER:
101 printk("USER "); 101 pr_cont("USER ");
102 break; 102 break;
103 case KSU_SUPERVISOR: 103 case KSU_SUPERVISOR:
104 printk("SUPERVISOR "); 104 pr_cont("SUPERVISOR ");
105 break; 105 break;
106 case KSU_KERNEL: 106 case KSU_KERNEL:
107 printk("KERNEL "); 107 pr_cont("KERNEL ");
108 break; 108 break;
109 default: 109 default:
110 printk("BAD_MODE "); 110 pr_cont("BAD_MODE ");
111 break; 111 break;
112 } 112 }
113 113
114 if (nr->sr & ST0_ERL) 114 if (nr->sr & ST0_ERL)
115 printk("ERL "); 115 pr_cont("ERL ");
116 if (nr->sr & ST0_EXL) 116 if (nr->sr & ST0_EXL)
117 printk("EXL "); 117 pr_cont("EXL ");
118 if (nr->sr & ST0_IE) 118 if (nr->sr & ST0_IE)
119 printk("IE "); 119 pr_cont("IE ");
120 printk("\n"); 120 pr_cont("\n");
121 121
122 printk("Cause : %08lx\n", nr->cause); 122 pr_emerg("Cause : %08lx\n", nr->cause);
123 printk("PrId : %08x\n", read_c0_prid()); 123 pr_emerg("PrId : %08x\n", read_c0_prid());
124 printk("BadVA : %016lx\n", nr->badva); 124 pr_emerg("BadVA : %016lx\n", nr->badva);
125 printk("CErr : %016lx\n", nr->cache_err); 125 pr_emerg("CErr : %016lx\n", nr->cache_err);
126 printk("NMI_SR: %016lx\n", nr->nmi_sr); 126 pr_emerg("NMI_SR: %016lx\n", nr->nmi_sr);
127 127
128 printk("\n"); 128 pr_emerg("\n");
129} 129}
130 130
131void nmi_dump_hub_irq(nasid_t nasid, int slice) 131void nmi_dump_hub_irq(nasid_t nasid, int slice)
132{ 132{
133 hubreg_t mask0, mask1, pend0, pend1; 133 u64 mask0, mask1, pend0, pend1;
134 134
135 if (slice == 0) { /* Slice A */ 135 if (slice == 0) { /* Slice A */
136 mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A); 136 mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A);
@@ -143,9 +143,9 @@ void nmi_dump_hub_irq(nasid_t nasid, int slice)
143 pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0); 143 pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);
144 pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1); 144 pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);
145 145
146 printk("PI_INT_MASK0: %16Lx PI_INT_MASK1: %16Lx\n", mask0, mask1); 146 pr_emerg("PI_INT_MASK0: %16llx PI_INT_MASK1: %16llx\n", mask0, mask1);
147 printk("PI_INT_PEND0: %16Lx PI_INT_PEND1: %16Lx\n", pend0, pend1); 147 pr_emerg("PI_INT_PEND0: %16llx PI_INT_PEND1: %16llx\n", pend0, pend1);
148 printk("\n\n"); 148 pr_emerg("\n\n");
149} 149}
150 150
151/* 151/*
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 545446dfe7fa..20b81209c6b8 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -177,7 +177,7 @@ static void ip27_send_ipi_mask(const struct cpumask *mask, unsigned int action)
177 ip27_send_ipi_single(i, action); 177 ip27_send_ipi_single(i, action);
178} 178}
179 179
180static void ip27_init_secondary(void) 180static void ip27_init_cpu(void)
181{ 181{
182 per_cpu_init(); 182 per_cpu_init();
183} 183}
@@ -235,9 +235,10 @@ static void __init ip27_prepare_cpus(unsigned int max_cpus)
235const struct plat_smp_ops ip27_smp_ops = { 235const struct plat_smp_ops ip27_smp_ops = {
236 .send_ipi_single = ip27_send_ipi_single, 236 .send_ipi_single = ip27_send_ipi_single,
237 .send_ipi_mask = ip27_send_ipi_mask, 237 .send_ipi_mask = ip27_send_ipi_mask,
238 .init_secondary = ip27_init_secondary, 238 .init_secondary = ip27_init_cpu,
239 .smp_finish = ip27_smp_finish, 239 .smp_finish = ip27_smp_finish,
240 .boot_secondary = ip27_boot_secondary, 240 .boot_secondary = ip27_boot_secondary,
241 .smp_setup = ip27_smp_setup, 241 .smp_setup = ip27_smp_setup,
242 .prepare_cpus = ip27_prepare_cpus, 242 .prepare_cpus = ip27_prepare_cpus,
243 .prepare_boot_cpu = ip27_init_cpu,
243}; 244};
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index 9d55247533a5..9b4b9ac621a3 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -38,20 +38,6 @@
38#include <asm/sn/sn0/hubio.h> 38#include <asm/sn/sn0/hubio.h>
39#include <asm/pci/bridge.h> 39#include <asm/pci/bridge.h>
40 40
41static void enable_rt_irq(struct irq_data *d)
42{
43}
44
45static void disable_rt_irq(struct irq_data *d)
46{
47}
48
49static struct irq_chip rt_irq_type = {
50 .name = "SN HUB RT timer",
51 .irq_mask = disable_rt_irq,
52 .irq_unmask = enable_rt_irq,
53};
54
55static int rt_next_event(unsigned long delta, struct clock_event_device *evt) 41static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
56{ 42{
57 unsigned int cpu = smp_processor_id(); 43 unsigned int cpu = smp_processor_id();
@@ -65,8 +51,6 @@ static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
65 return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0; 51 return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
66} 52}
67 53
68unsigned int rt_timer_irq;
69
70static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent); 54static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
71static DEFINE_PER_CPU(char [11], hub_rt_name); 55static DEFINE_PER_CPU(char [11], hub_rt_name);
72 56
@@ -87,6 +71,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
87 71
88struct irqaction hub_rt_irqaction = { 72struct irqaction hub_rt_irqaction = {
89 .handler = hub_rt_counter_handler, 73 .handler = hub_rt_counter_handler,
74 .percpu_dev_id = &hub_rt_clockevent,
90 .flags = IRQF_PERCPU | IRQF_TIMER, 75 .flags = IRQF_PERCPU | IRQF_TIMER,
91 .name = "hub-rt", 76 .name = "hub-rt",
92}; 77};
@@ -107,7 +92,6 @@ void hub_rt_clock_event_init(void)
107 unsigned int cpu = smp_processor_id(); 92 unsigned int cpu = smp_processor_id();
108 struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu); 93 struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
109 unsigned char *name = per_cpu(hub_rt_name, cpu); 94 unsigned char *name = per_cpu(hub_rt_name, cpu);
110 int irq = rt_timer_irq;
111 95
112 sprintf(name, "hub-rt %d", cpu); 96 sprintf(name, "hub-rt %d", cpu);
113 cd->name = name; 97 cd->name = name;
@@ -118,29 +102,19 @@ void hub_rt_clock_event_init(void)
118 cd->min_delta_ns = clockevent_delta2ns(0x300, cd); 102 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
119 cd->min_delta_ticks = 0x300; 103 cd->min_delta_ticks = 0x300;
120 cd->rating = 200; 104 cd->rating = 200;
121 cd->irq = irq; 105 cd->irq = IP27_RT_TIMER_IRQ;
122 cd->cpumask = cpumask_of(cpu); 106 cd->cpumask = cpumask_of(cpu);
123 cd->set_next_event = rt_next_event; 107 cd->set_next_event = rt_next_event;
124 clockevents_register_device(cd); 108 clockevents_register_device(cd);
109
110 enable_percpu_irq(IP27_RT_TIMER_IRQ, IRQ_TYPE_NONE);
125} 111}
126 112
127static void __init hub_rt_clock_event_global_init(void) 113static void __init hub_rt_clock_event_global_init(void)
128{ 114{
129 int irq; 115 irq_set_handler(IP27_RT_TIMER_IRQ, handle_percpu_devid_irq);
130 116 irq_set_percpu_devid(IP27_RT_TIMER_IRQ);
131 do { 117 setup_percpu_irq(IP27_RT_TIMER_IRQ, &hub_rt_irqaction);
132 smp_wmb();
133 irq = rt_timer_irq;
134 if (irq)
135 break;
136
137 irq = allocate_irqno();
138 if (irq < 0)
139 panic("Allocation of irq number for timer failed");
140 } while (xchg(&rt_timer_irq, irq));
141
142 irq_set_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
143 setup_irq(irq, &hub_rt_irqaction);
144} 118}
145 119
146static u64 hub_rt_read(struct clocksource *cs) 120static u64 hub_rt_read(struct clocksource *cs)
@@ -194,8 +168,6 @@ void cpu_time_init(void)
194 panic("No information about myself?"); 168 panic("No information about myself?");
195 169
196 printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); 170 printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
197
198 set_c0_status(SRB_TIMOCLK);
199} 171}
200 172
201void hub_rtc_init(cnodeid_t cnode) 173void hub_rtc_init(cnodeid_t cnode)
diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
index 4fe5678ba74d..ce06aaa115ae 100644
--- a/arch/mips/sgi-ip27/ip27-xtalk.c
+++ b/arch/mips/sgi-ip27/ip27-xtalk.c
@@ -99,7 +99,7 @@ static int xbow_probe(nasid_t nasid)
99 return 0; 99 return 0;
100} 100}
101 101
102void xtalk_probe_node(cnodeid_t nid) 102static void xtalk_probe_node(cnodeid_t nid)
103{ 103{
104 volatile u64 hubreg; 104 volatile u64 hubreg;
105 nasid_t nasid; 105 nasid_t nasid;
@@ -133,3 +133,14 @@ void xtalk_probe_node(cnodeid_t nid)
133 break; 133 break;
134 } 134 }
135} 135}
136
137static int __init xtalk_init(void)
138{
139 cnodeid_t cnode;
140
141 for_each_online_node(cnode)
142 xtalk_probe_node(cnode);
143
144 return 0;
145}
146arch_initcall(xtalk_init);
diff --git a/drivers/soc/lantiq/Makefile b/drivers/soc/lantiq/Makefile
index be9e866d53e5..35aa86bd1023 100644
--- a/drivers/soc/lantiq/Makefile
+++ b/drivers/soc/lantiq/Makefile
@@ -1,2 +1 @@
1obj-y += fpi-bus.o obj-y += fpi-bus.o
2obj-$(CONFIG_XRX200_PHY_FW) += gphy.o
diff --git a/drivers/soc/lantiq/gphy.c b/drivers/soc/lantiq/gphy.c
deleted file mode 100644
index feeb17cebc25..000000000000
--- a/drivers/soc/lantiq/gphy.c
+++ /dev/null
@@ -1,224 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 John Crispin <blogic@phrozen.org>
7 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
8 * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
9 */
10
11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/dma-mapping.h>
14#include <linux/firmware.h>
15#include <linux/mfd/syscon.h>
16#include <linux/module.h>
17#include <linux/reboot.h>
18#include <linux/regmap.h>
19#include <linux/reset.h>
20#include <linux/of_device.h>
21#include <linux/of_platform.h>
22#include <linux/property.h>
23#include <dt-bindings/mips/lantiq_rcu_gphy.h>
24
25#include <lantiq_soc.h>
26
27#define XRX200_GPHY_FW_ALIGN (16 * 1024)
28
29struct xway_gphy_priv {
30 struct clk *gphy_clk_gate;
31 struct reset_control *gphy_reset;
32 struct reset_control *gphy_reset2;
33 void __iomem *membase;
34 char *fw_name;
35};
36
37struct xway_gphy_match_data {
38 char *fe_firmware_name;
39 char *ge_firmware_name;
40};
41
42static const struct xway_gphy_match_data xrx200a1x_gphy_data = {
43 .fe_firmware_name = "lantiq/xrx200_phy22f_a14.bin",
44 .ge_firmware_name = "lantiq/xrx200_phy11g_a14.bin",
45};
46
47static const struct xway_gphy_match_data xrx200a2x_gphy_data = {
48 .fe_firmware_name = "lantiq/xrx200_phy22f_a22.bin",
49 .ge_firmware_name = "lantiq/xrx200_phy11g_a22.bin",
50};
51
52static const struct xway_gphy_match_data xrx300_gphy_data = {
53 .fe_firmware_name = "lantiq/xrx300_phy22f_a21.bin",
54 .ge_firmware_name = "lantiq/xrx300_phy11g_a21.bin",
55};
56
57static const struct of_device_id xway_gphy_match[] = {
58 { .compatible = "lantiq,xrx200a1x-gphy", .data = &xrx200a1x_gphy_data },
59 { .compatible = "lantiq,xrx200a2x-gphy", .data = &xrx200a2x_gphy_data },
60 { .compatible = "lantiq,xrx300-gphy", .data = &xrx300_gphy_data },
61 { .compatible = "lantiq,xrx330-gphy", .data = &xrx300_gphy_data },
62 {},
63};
64MODULE_DEVICE_TABLE(of, xway_gphy_match);
65
66static int xway_gphy_load(struct device *dev, struct xway_gphy_priv *priv,
67 dma_addr_t *dev_addr)
68{
69 const struct firmware *fw;
70 void *fw_addr;
71 dma_addr_t dma_addr;
72 size_t size;
73 int ret;
74
75 ret = request_firmware(&fw, priv->fw_name, dev);
76 if (ret) {
77 dev_err(dev, "failed to load firmware: %s, error: %i\n",
78 priv->fw_name, ret);
79 return ret;
80 }
81
82 /*
83 * GPHY cores need the firmware code in a persistent and contiguous
84 * memory area with a 16 kB boundary aligned start address.
85 */
86 size = fw->size + XRX200_GPHY_FW_ALIGN;
87
88 fw_addr = dmam_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL);
89 if (fw_addr) {
90 fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN);
91 *dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
92 memcpy(fw_addr, fw->data, fw->size);
93 } else {
94 dev_err(dev, "failed to alloc firmware memory\n");
95 ret = -ENOMEM;
96 }
97
98 release_firmware(fw);
99
100 return ret;
101}
102
103static int xway_gphy_of_probe(struct platform_device *pdev,
104 struct xway_gphy_priv *priv)
105{
106 struct device *dev = &pdev->dev;
107 const struct xway_gphy_match_data *gphy_fw_name_cfg;
108 u32 gphy_mode;
109 int ret;
110 struct resource *res_gphy;
111
112 gphy_fw_name_cfg = of_device_get_match_data(dev);
113
114 priv->gphy_clk_gate = devm_clk_get(dev, NULL);
115 if (IS_ERR(priv->gphy_clk_gate)) {
116 dev_err(dev, "Failed to lookup gate clock\n");
117 return PTR_ERR(priv->gphy_clk_gate);
118 }
119
120 res_gphy = platform_get_resource(pdev, IORESOURCE_MEM, 0);
121 priv->membase = devm_ioremap_resource(dev, res_gphy);
122 if (IS_ERR(priv->membase))
123 return PTR_ERR(priv->membase);
124
125 priv->gphy_reset = devm_reset_control_get(dev, "gphy");
126 if (IS_ERR(priv->gphy_reset)) {
127 if (PTR_ERR(priv->gphy_reset) != -EPROBE_DEFER)
128 dev_err(dev, "Failed to lookup gphy reset\n");
129 return PTR_ERR(priv->gphy_reset);
130 }
131
132 priv->gphy_reset2 = devm_reset_control_get_optional(dev, "gphy2");
133 if (IS_ERR(priv->gphy_reset2))
134 return PTR_ERR(priv->gphy_reset2);
135
136 ret = device_property_read_u32(dev, "lantiq,gphy-mode", &gphy_mode);
137 /* Default to GE mode */
138 if (ret)
139 gphy_mode = GPHY_MODE_GE;
140
141 switch (gphy_mode) {
142 case GPHY_MODE_FE:
143 priv->fw_name = gphy_fw_name_cfg->fe_firmware_name;
144 break;
145 case GPHY_MODE_GE:
146 priv->fw_name = gphy_fw_name_cfg->ge_firmware_name;
147 break;
148 default:
149 dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
150 return -EINVAL;
151 }
152
153 return 0;
154}
155
156static int xway_gphy_probe(struct platform_device *pdev)
157{
158 struct device *dev = &pdev->dev;
159 struct xway_gphy_priv *priv;
160 dma_addr_t fw_addr = 0;
161 int ret;
162
163 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
164 if (!priv)
165 return -ENOMEM;
166
167 ret = xway_gphy_of_probe(pdev, priv);
168 if (ret)
169 return ret;
170
171 ret = clk_prepare_enable(priv->gphy_clk_gate);
172 if (ret)
173 return ret;
174
175 ret = xway_gphy_load(dev, priv, &fw_addr);
176 if (ret) {
177 clk_disable_unprepare(priv->gphy_clk_gate);
178 return ret;
179 }
180
181 reset_control_assert(priv->gphy_reset);
182 reset_control_assert(priv->gphy_reset2);
183
184 iowrite32be(fw_addr, priv->membase);
185
186 reset_control_deassert(priv->gphy_reset);
187 reset_control_deassert(priv->gphy_reset2);
188
189 platform_set_drvdata(pdev, priv);
190
191 return ret;
192}
193
194static int xway_gphy_remove(struct platform_device *pdev)
195{
196 struct xway_gphy_priv *priv = platform_get_drvdata(pdev);
197
198 iowrite32be(0, priv->membase);
199
200 clk_disable_unprepare(priv->gphy_clk_gate);
201
202 return 0;
203}
204
205static struct platform_driver xway_gphy_driver = {
206 .probe = xway_gphy_probe,
207 .remove = xway_gphy_remove,
208 .driver = {
209 .name = "xway-rcu-gphy",
210 .of_match_table = xway_gphy_match,
211 },
212};
213
214module_platform_driver(xway_gphy_driver);
215
216MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin");
217MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin");
218MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin");
219MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin");
220MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin");
221MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin");
222MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
223MODULE_DESCRIPTION("Lantiq XWAY GPHY Firmware Loader");
224MODULE_LICENSE("GPL");
diff --git a/include/dt-bindings/clock/ath79-clk.h b/include/dt-bindings/clock/ath79-clk.h
index 27359ad83904..dcc679a7ad85 100644
--- a/include/dt-bindings/clock/ath79-clk.h
+++ b/include/dt-bindings/clock/ath79-clk.h
@@ -13,7 +13,9 @@
13#define ATH79_CLK_CPU 0 13#define ATH79_CLK_CPU 0
14#define ATH79_CLK_DDR 1 14#define ATH79_CLK_DDR 1
15#define ATH79_CLK_AHB 2 15#define ATH79_CLK_AHB 2
16#define ATH79_CLK_REF 3
17#define ATH79_CLK_MDIO 4
16 18
17#define ATH79_CLK_END 3 19#define ATH79_CLK_END 5
18 20
19#endif /* __DT_BINDINGS_ATH79_CLK_H */ 21#endif /* __DT_BINDINGS_ATH79_CLK_H */