summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-05 11:28:25 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-05 11:28:25 -0800
commitd9862cfbe2099deb83f0e9c1932c91f2d9c50464 (patch)
tree7092ef41113269f30b5429868a9d161e171c746d /arch/mips
parent8feed3efa8022107bcb3432ac3ec9917e078ae70 (diff)
parentaeb669d41ffabb91b1542f1f802cb12a989fced0 (diff)
downloadblackbird-op-linux-d9862cfbe2099deb83f0e9c1932c91f2d9c50464.tar.gz
blackbird-op-linux-d9862cfbe2099deb83f0e9c1932c91f2d9c50464.zip
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() ...
Diffstat (limited to 'arch/mips')
-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
114 files changed, 1607 insertions, 4335 deletions
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
select COMMON_CLK
select CLKDEV_LOOKUP
select IRQ_MIPS_CPU
- select MIPS_MACHINE
select SYS_HAS_CPU_MIPS32_R2
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
@@ -391,7 +390,7 @@ config MACH_INGENIC
select GPIOLIB
select COMMON_CLK
select GENERIC_IRQ_CHIP
- select BUILTIN_DTB
+ select BUILTIN_DTB if MIPS_NO_APPENDED_DTB
select USE_OF
select LIBFDT
@@ -676,6 +675,7 @@ config SGI_IP27
select DEFAULT_SGI_PARTITION
select SYS_HAS_EARLY_PRINTK
select HAVE_PCI
+ select IRQ_MIPS_CPU
select NR_CPUS_DEFAULT_64
select SYS_HAS_CPU_R10000
select SYS_SUPPORTS_64BIT_KERNEL
@@ -1124,7 +1124,6 @@ config DMA_NONCOHERENT
bool
select ARCH_HAS_DMA_MMAP_PGPROT
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
- select ARCH_HAS_SYNC_DMA_FOR_CPU
select NEED_DMA_MAP_STATE
select ARCH_HAS_DMA_COHERENT_TO_PFN
select DMA_NONCOHERENT_CACHE_SYNC
@@ -1556,6 +1555,7 @@ config CPU_MIPS64_R6
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
select CPU_SUPPORTS_MSA
select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32
select HAVE_KVM
@@ -1881,7 +1881,7 @@ config CPU_LOONGSON2
config CPU_LOONGSON1
bool
select CPU_MIPS32
- select CPU_MIPSR1
+ select CPU_MIPSR2
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
@@ -1943,9 +1943,11 @@ config SYS_HAS_CPU_MIPS32_R3_5
config SYS_HAS_CPU_MIPS32_R5
bool
+ select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
config SYS_HAS_CPU_MIPS32_R6
bool
+ select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
config SYS_HAS_CPU_MIPS64_R1
bool
@@ -1955,6 +1957,7 @@ config SYS_HAS_CPU_MIPS64_R2
config SYS_HAS_CPU_MIPS64_R6
bool
+ select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
config SYS_HAS_CPU_R3000
bool
@@ -1991,6 +1994,7 @@ config SYS_HAS_CPU_R8000
config SYS_HAS_CPU_R10000
bool
+ select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
config SYS_HAS_CPU_RM7000
bool
@@ -2019,6 +2023,7 @@ config SYS_HAS_CPU_BMIPS4380
config SYS_HAS_CPU_BMIPS5000
bool
select SYS_HAS_CPU_BMIPS
+ select ARCH_HAS_SYNC_DMA_FOR_CPU
config SYS_HAS_CPU_XLR
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)
cflags-$(toolchain-crc) += -DTOOLCHAIN_SUPPORTS_CRC
toolchain-dsp := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mdsp)
cflags-$(toolchain-dsp) += -DTOOLCHAIN_SUPPORTS_DSP
+toolchain-ginv := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mginv)
+cflags-$(toolchain-ginv) += -DTOOLCHAIN_SUPPORTS_GINV
#
# 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 @@
# SPDX-License-Identifier: GPL-2.0
if ATH79
-menu "Atheros AR71XX/AR724X/AR913X machine selection"
-
-config ATH79_MACH_AP121
- bool "Atheros AP121 reference board"
- select SOC_AR933X
- select ATH79_DEV_GPIO_BUTTONS
- select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
- select ATH79_DEV_USB
- select ATH79_DEV_WMAC
- help
- Say 'Y' here if you want your kernel to support the
- Atheros AP121 reference board.
-
-config ATH79_MACH_AP136
- bool "Atheros AP136 reference board"
- select SOC_QCA955X
- select ATH79_DEV_GPIO_BUTTONS
- select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
- select ATH79_DEV_USB
- select ATH79_DEV_WMAC
- help
- Say 'Y' here if you want your kernel to support the
- Atheros AP136 reference board.
-
-config ATH79_MACH_AP81
- bool "Atheros AP81 reference board"
- select SOC_AR913X
- select ATH79_DEV_GPIO_BUTTONS
- select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
- select ATH79_DEV_USB
- select ATH79_DEV_WMAC
- help
- Say 'Y' here if you want your kernel to support the
- Atheros AP81 reference board.
-
-config ATH79_MACH_DB120
- bool "Atheros DB120 reference board"
- select SOC_AR934X
- select ATH79_DEV_GPIO_BUTTONS
- select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
- select ATH79_DEV_USB
- select ATH79_DEV_WMAC
- help
- Say 'Y' here if you want your kernel to support the
- Atheros DB120 reference board.
-
-config ATH79_MACH_PB44
- bool "Atheros PB44 reference board"
- select SOC_AR71XX
- select ATH79_DEV_GPIO_BUTTONS
- select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
- select ATH79_DEV_USB
- help
- Say 'Y' here if you want your kernel to support the
- Atheros PB44 reference board.
-
-config ATH79_MACH_UBNT_XM
- bool "Ubiquiti Networks XM (rev 1.0) board"
- select SOC_AR724X
- select ATH79_DEV_GPIO_BUTTONS
- select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
- help
- Say 'Y' here if you want your kernel to support the
- Ubiquiti Networks XM (rev 1.0) board.
-
-endmenu
-
config SOC_AR71XX
select HAVE_PCI
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 @@
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
-obj-y := prom.o setup.o irq.o common.o clock.o
+obj-y := prom.o setup.o common.o clock.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_PCI) += pci.o
-
-#
-# Devices
-#
-obj-y += dev-common.o
-obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
-obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
-obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o
-obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o
-obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o
-
-#
-# Machines
-#
-obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
-obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o
-obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
-obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o
-obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
-obj-$(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 @@
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include "common.h"
-#include "machtypes.h"
#define AR71XX_BASE_FREQ 40000000
#define AR724X_BASE_FREQ 40000000
@@ -37,24 +36,63 @@ static struct clk_onecell_data clk_data = {
.clk_num = ARRAY_SIZE(clks),
};
-static struct clk *__init ath79_add_sys_clkdev(
- const char *id, unsigned long rate)
+static const char * const clk_names[ATH79_CLK_END] = {
+ [ATH79_CLK_CPU] = "cpu",
+ [ATH79_CLK_DDR] = "ddr",
+ [ATH79_CLK_AHB] = "ahb",
+ [ATH79_CLK_REF] = "ref",
+ [ATH79_CLK_MDIO] = "mdio",
+};
+
+static const char * __init ath79_clk_name(int type)
{
- struct clk *clk;
- int err;
+ BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]);
+ return clk_names[type];
+}
- clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
+static void __init __ath79_set_clk(int type, const char *name, struct clk *clk)
+{
if (IS_ERR(clk))
- panic("failed to allocate %s clock structure", id);
+ panic("failed to allocate %s clock structure", clk_names[type]);
- err = clk_register_clkdev(clk, id, NULL);
- if (err)
- panic("unable to register %s clock device", id);
+ clks[type] = clk;
+ clk_register_clkdev(clk, name, NULL);
+}
+static struct clk * __init ath79_set_clk(int type, unsigned long rate)
+{
+ const char *name = ath79_clk_name(type);
+ struct clk *clk;
+
+ clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate);
+ __ath79_set_clk(type, name, clk);
return clk;
}
-static void __init ar71xx_clocks_init(void)
+static struct clk * __init ath79_set_ff_clk(int type, const char *parent,
+ unsigned int mult, unsigned int div)
+{
+ const char *name = ath79_clk_name(type);
+ struct clk *clk;
+
+ clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div);
+ __ath79_set_clk(type, name, clk);
+ return clk;
+}
+
+static unsigned long __init ath79_setup_ref_clk(unsigned long rate)
+{
+ struct clk *clk = clks[ATH79_CLK_REF];
+
+ if (clk)
+ rate = clk_get_rate(clk);
+ else
+ clk = ath79_set_clk(ATH79_CLK_REF, rate);
+
+ return rate;
+}
+
+static void __init ar71xx_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -64,9 +102,9 @@ static void __init ar71xx_clocks_init(void)
u32 freq;
u32 div;
- ref_rate = AR71XX_BASE_FREQ;
+ ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ);
- pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
+ pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG);
div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1;
freq = div * ref_rate;
@@ -80,31 +118,17 @@ static void __init ar71xx_clocks_init(void)
div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
ahb_rate = cpu_rate / div;
- ath79_add_sys_clkdev("ref", ref_rate);
- clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate);
- clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate);
- clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
-
- clk_add_alias("wdt", NULL, "ahb", NULL);
- clk_add_alias("uart", NULL, "ahb", NULL);
+ ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
+ ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
+ ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
}
-static struct clk * __init ath79_reg_ffclk(const char *name,
- const char *parent_name, unsigned int mult, unsigned int div)
+static void __init ar724x_clocks_init(void __iomem *pll_base)
{
- struct clk *clk;
-
- clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div);
- if (IS_ERR(clk))
- panic("failed to allocate %s clock structure", name);
-
- return clk;
-}
-
-static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base)
-{
- u32 pll;
u32 mult, div, ddr_div, ahb_div;
+ u32 pll;
+
+ ath79_setup_ref_clk(AR71XX_BASE_FREQ);
pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
@@ -114,30 +138,14 @@ static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base)
ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
- clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div);
- clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div);
- clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div);
-}
-
-static void __init ar724x_clocks_init(void)
-{
- struct clk *ref_clk;
-
- ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ);
-
- ar724x_clk_init(ref_clk, ath79_pll_base);
-
- /* just make happy plat_time_init() from arch/mips/ath79/setup.c */
- clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL);
- clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL);
- clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL);
-
- clk_add_alias("wdt", NULL, "ahb", NULL);
- clk_add_alias("uart", NULL, "ahb", NULL);
+ ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div);
+ ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div);
+ ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div);
}
-static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base)
+static void __init ar933x_clocks_init(void __iomem *pll_base)
{
+ unsigned long ref_rate;
u32 clock_ctrl;
u32 ref_div;
u32 ninit_mul;
@@ -146,6 +154,15 @@ static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base)
u32 cpu_div;
u32 ddr_div;
u32 ahb_div;
+ u32 t;
+
+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
+ if (t & AR933X_BOOTSTRAP_REF_CLK_40)
+ ref_rate = (40 * 1000 * 1000);
+ else
+ ref_rate = (25 * 1000 * 1000);
+
+ ath79_setup_ref_clk(ref_rate);
clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG);
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)
AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
}
- clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref",
- ninit_mul, ref_div * out_div * cpu_div);
- clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref",
- ninit_mul, ref_div * out_div * ddr_div);
- clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref",
- ninit_mul, ref_div * out_div * ahb_div);
-}
-
-static void __init ar933x_clocks_init(void)
-{
- struct clk *ref_clk;
- unsigned long ref_rate;
- u32 t;
-
- t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
- if (t & AR933X_BOOTSTRAP_REF_CLK_40)
- ref_rate = (40 * 1000 * 1000);
- else
- ref_rate = (25 * 1000 * 1000);
-
- ref_clk = ath79_add_sys_clkdev("ref", ref_rate);
-
- ar9330_clk_init(ref_clk, ath79_pll_base);
-
- /* just make happy plat_time_init() from arch/mips/ath79/setup.c */
- clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL);
- clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL);
- clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL);
-
- clk_add_alias("wdt", NULL, "ahb", NULL);
- clk_add_alias("uart", NULL, "ref", NULL);
+ ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul,
+ ref_div * out_div * cpu_div);
+ ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul,
+ ref_div * out_div * ddr_div);
+ ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul,
+ ref_div * out_div * ahb_div);
}
static 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,
return ret;
}
-static void __init ar934x_clocks_init(void)
+static void __init ar934x_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -258,6 +250,8 @@ static void __init ar934x_clocks_init(void)
else
ref_rate = 25 * 1000 * 1000;
+ ref_rate = ath79_setup_ref_clk(ref_rate);
+
pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
@@ -270,7 +264,7 @@ static void __init ar934x_clocks_init(void)
AR934X_SRIF_DPLL1_REFDIV_MASK;
frac = 1 << 18;
} else {
- pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
+ pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG);
out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
@@ -297,7 +291,7 @@ static void __init ar934x_clocks_init(void)
AR934X_SRIF_DPLL1_REFDIV_MASK;
frac = 1 << 18;
} else {
- pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
+ pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG);
out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
@@ -312,7 +306,7 @@ static void __init ar934x_clocks_init(void)
ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
nfrac, frac, out_div);
- clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
+ clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
@@ -344,18 +338,18 @@ static void __init ar934x_clocks_init(void)
else
ahb_rate = cpu_pll / (postdiv + 1);
- ath79_add_sys_clkdev("ref", ref_rate);
- clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate);
- clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate);
- clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
+ ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
+ ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
+ ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
- clk_add_alias("wdt", NULL, "ref", NULL);
- clk_add_alias("uart", NULL, "ref", NULL);
+ clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
+ if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL)
+ ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000);
iounmap(dpll_base);
}
-static void __init qca953x_clocks_init(void)
+static void __init qca953x_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -371,7 +365,9 @@ static void __init qca953x_clocks_init(void)
else
ref_rate = 25 * 1000 * 1000;
- pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG);
+ ref_rate = ath79_setup_ref_clk(ref_rate);
+
+ pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG);
out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
@@ -385,7 +381,7 @@ static void __init qca953x_clocks_init(void)
cpu_pll += frac * (ref_rate >> 6) / ref_div;
cpu_pll /= (1 << out_div);
- pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG);
+ pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG);
out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
@@ -399,7 +395,7 @@ static void __init qca953x_clocks_init(void)
ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
ddr_pll /= (1 << out_div);
- clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG);
+ clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG);
postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
@@ -431,16 +427,12 @@ static void __init qca953x_clocks_init(void)
else
ahb_rate = cpu_pll / (postdiv + 1);
- ath79_add_sys_clkdev("ref", ref_rate);
- ath79_add_sys_clkdev("cpu", cpu_rate);
- ath79_add_sys_clkdev("ddr", ddr_rate);
- ath79_add_sys_clkdev("ahb", ahb_rate);
-
- clk_add_alias("wdt", NULL, "ref", NULL);
- clk_add_alias("uart", NULL, "ref", NULL);
+ ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
+ ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
+ ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
}
-static void __init qca955x_clocks_init(void)
+static void __init qca955x_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -456,7 +448,9 @@ static void __init qca955x_clocks_init(void)
else
ref_rate = 25 * 1000 * 1000;
- pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG);
+ ref_rate = ath79_setup_ref_clk(ref_rate);
+
+ pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG);
out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK;
ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
@@ -470,7 +464,7 @@ static void __init qca955x_clocks_init(void)
cpu_pll += frac * ref_rate / (ref_div * (1 << 6));
cpu_pll /= (1 << out_div);
- pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG);
+ pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG);
out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK;
ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
@@ -484,7 +478,7 @@ static void __init qca955x_clocks_init(void)
ddr_pll += frac * ref_rate / (ref_div * (1 << 10));
ddr_pll /= (1 << out_div);
- clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG);
+ clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG);
postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
@@ -516,16 +510,12 @@ static void __init qca955x_clocks_init(void)
else
ahb_rate = cpu_pll / (postdiv + 1);
- ath79_add_sys_clkdev("ref", ref_rate);
- clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate);
- clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate);
- clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
-
- clk_add_alias("wdt", NULL, "ref", NULL);
- clk_add_alias("uart", NULL, "ref", NULL);
+ ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
+ ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
+ ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
}
-static void __init qca956x_clocks_init(void)
+static void __init qca956x_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -551,13 +541,15 @@ static void __init qca956x_clocks_init(void)
else
ref_rate = 25 * 1000 * 1000;
- pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG);
+ ref_rate = ath79_setup_ref_clk(ref_rate);
+
+ pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG);
out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
- pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG);
+ pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG);
nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
@@ -570,12 +562,12 @@ static void __init qca956x_clocks_init(void)
cpu_pll += (hfrac >> 13) * ref_rate / ref_div;
cpu_pll /= (1 << out_div);
- pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG);
+ pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG);
out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
- pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG);
+ pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG);
nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
@@ -588,7 +580,7 @@ static void __init qca956x_clocks_init(void)
ddr_pll += (hfrac >> 13) * ref_rate / ref_div;
ddr_pll /= (1 << out_div);
- clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG);
+ clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG);
postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
@@ -620,72 +612,19 @@ static void __init qca956x_clocks_init(void)
else
ahb_rate = cpu_pll / (postdiv + 1);
- ath79_add_sys_clkdev("ref", ref_rate);
- ath79_add_sys_clkdev("cpu", cpu_rate);
- ath79_add_sys_clkdev("ddr", ddr_rate);
- ath79_add_sys_clkdev("ahb", ahb_rate);
-
- clk_add_alias("wdt", NULL, "ref", NULL);
- clk_add_alias("uart", NULL, "ref", NULL);
-}
-
-void __init ath79_clocks_init(void)
-{
- if (soc_is_ar71xx())
- ar71xx_clocks_init();
- else if (soc_is_ar724x() || soc_is_ar913x())
- ar724x_clocks_init();
- else if (soc_is_ar933x())
- ar933x_clocks_init();
- else if (soc_is_ar934x())
- ar934x_clocks_init();
- else if (soc_is_qca953x())
- qca953x_clocks_init();
- else if (soc_is_qca955x())
- qca955x_clocks_init();
- else if (soc_is_qca956x() || soc_is_tp9343())
- qca956x_clocks_init();
- else
- BUG();
-}
-
-unsigned long __init
-ath79_get_sys_clk_rate(const char *id)
-{
- struct clk *clk;
- unsigned long rate;
-
- clk = clk_get(NULL, id);
- if (IS_ERR(clk))
- panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk));
-
- rate = clk_get_rate(clk);
- clk_put(clk);
-
- return rate;
+ ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
+ ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
+ ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
}
-#ifdef CONFIG_OF
static void __init ath79_clocks_init_dt(struct device_node *np)
{
- of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-}
-
-CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt);
-
-static void __init ath79_clocks_init_dt_ng(struct device_node *np)
-{
struct clk *ref_clk;
void __iomem *pll_base;
ref_clk = of_clk_get(np, 0);
- if (IS_ERR(ref_clk)) {
- pr_err("%pOF: of_clk_get failed\n", np);
- goto err;
- }
+ if (!IS_ERR(ref_clk))
+ clks[ATH79_CLK_REF] = ref_clk;
pll_base = of_iomap(np, 0);
if (!pll_base) {
@@ -693,14 +632,24 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np)
goto err_clk;
}
- if (of_device_is_compatible(np, "qca,ar9130-pll"))
- ar724x_clk_init(ref_clk, pll_base);
+ if (of_device_is_compatible(np, "qca,ar7100-pll"))
+ ar71xx_clocks_init(pll_base);
+ else if (of_device_is_compatible(np, "qca,ar7240-pll") ||
+ of_device_is_compatible(np, "qca,ar9130-pll"))
+ ar724x_clocks_init(pll_base);
else if (of_device_is_compatible(np, "qca,ar9330-pll"))
- ar9330_clk_init(ref_clk, pll_base);
- else {
- pr_err("%pOF: could not find any appropriate clk_init()\n", np);
- goto err_iounmap;
- }
+ ar933x_clocks_init(pll_base);
+ else if (of_device_is_compatible(np, "qca,ar9340-pll"))
+ ar934x_clocks_init(pll_base);
+ else if (of_device_is_compatible(np, "qca,qca9530-pll"))
+ qca953x_clocks_init(pll_base);
+ else if (of_device_is_compatible(np, "qca,qca9550-pll"))
+ qca955x_clocks_init(pll_base);
+ else if (of_device_is_compatible(np, "qca,qca9560-pll"))
+ qca956x_clocks_init(pll_base);
+
+ if (!clks[ATH79_CLK_MDIO])
+ clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF];
if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
pr_err("%pOF: could not register clk provider\n", np);
@@ -714,10 +663,13 @@ err_iounmap:
err_clk:
clk_put(ref_clk);
-
-err:
- return;
}
-CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng);
-CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng);
-#endif
+
+CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt);
+CLK_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 @@
#define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024)
#define ATH79_MEM_SIZE_MAX (256 * 1024 * 1024)
-void ath79_clocks_init(void);
-unsigned long ath79_get_sys_clk_rate(const char *id);
-
void ath79_ddr_ctrl_init(void);
-void ath79_gpio_init(void);
-
#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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X common devices
- *
- * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * Parts of this file are based on Atheros' 2.6.15 BSP
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/gpio-ath79.h>
-#include <linux/serial_8250.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <asm/mach-ath79/ath79.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-#include "common.h"
-#include "dev-common.h"
-
-static struct resource ath79_uart_resources[] = {
- {
- .start = AR71XX_UART_BASE,
- .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
-static struct plat_serial8250_port ath79_uart_data[] = {
- {
- .mapbase = AR71XX_UART_BASE,
- .irq = ATH79_MISC_IRQ(3),
- .flags = AR71XX_UART_FLAGS,
- .iotype = UPIO_MEM32,
- .regshift = 2,
- }, {
- /* terminating entry */
- }
-};
-
-static struct platform_device ath79_uart_device = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .resource = ath79_uart_resources,
- .num_resources = ARRAY_SIZE(ath79_uart_resources),
- .dev = {
- .platform_data = ath79_uart_data
- },
-};
-
-static struct resource ar933x_uart_resources[] = {
- {
- .start = AR933X_UART_BASE,
- .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = ATH79_MISC_IRQ(3),
- .end = ATH79_MISC_IRQ(3),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device ar933x_uart_device = {
- .name = "ar933x-uart",
- .id = -1,
- .resource = ar933x_uart_resources,
- .num_resources = ARRAY_SIZE(ar933x_uart_resources),
-};
-
-void __init ath79_register_uart(void)
-{
- unsigned long uart_clk_rate;
-
- uart_clk_rate = ath79_get_sys_clk_rate("uart");
-
- if (soc_is_ar71xx() ||
- soc_is_ar724x() ||
- soc_is_ar913x() ||
- soc_is_ar934x() ||
- soc_is_qca955x()) {
- ath79_uart_data[0].uartclk = uart_clk_rate;
- platform_device_register(&ath79_uart_device);
- } else if (soc_is_ar933x()) {
- platform_device_register(&ar933x_uart_device);
- } else {
- BUG();
- }
-}
-
-void __init ath79_register_wdt(void)
-{
- struct resource res;
-
- memset(&res, 0, sizeof(res));
-
- res.flags = IORESOURCE_MEM;
- res.start = AR71XX_RESET_BASE + AR71XX_RESET_REG_WDOG_CTRL;
- res.end = res.start + 0x8 - 1;
-
- platform_device_register_simple("ath79-wdt", -1, &res, 1);
-}
-
-static struct ath79_gpio_platform_data ath79_gpio_pdata;
-
-static struct resource ath79_gpio_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- .start = AR71XX_GPIO_BASE,
- .end = AR71XX_GPIO_BASE + AR71XX_GPIO_SIZE - 1,
- },
- {
- .start = ATH79_MISC_IRQ(2),
- .end = ATH79_MISC_IRQ(2),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device ath79_gpio_device = {
- .name = "ath79-gpio",
- .id = -1,
- .resource = ath79_gpio_resources,
- .num_resources = ARRAY_SIZE(ath79_gpio_resources),
- .dev = {
- .platform_data = &ath79_gpio_pdata
- },
-};
-
-void __init ath79_gpio_init(void)
-{
- if (soc_is_ar71xx()) {
- ath79_gpio_pdata.ngpios = AR71XX_GPIO_COUNT;
- } else if (soc_is_ar7240()) {
- ath79_gpio_pdata.ngpios = AR7240_GPIO_COUNT;
- } else if (soc_is_ar7241() || soc_is_ar7242()) {
- ath79_gpio_pdata.ngpios = AR7241_GPIO_COUNT;
- } else if (soc_is_ar913x()) {
- ath79_gpio_pdata.ngpios = AR913X_GPIO_COUNT;
- } else if (soc_is_ar933x()) {
- ath79_gpio_pdata.ngpios = AR933X_GPIO_COUNT;
- } else if (soc_is_ar934x()) {
- ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT;
- ath79_gpio_pdata.oe_inverted = 1;
- } else if (soc_is_qca955x()) {
- ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT;
- ath79_gpio_pdata.oe_inverted = 1;
- } else {
- BUG();
- }
-
- platform_device_register(&ath79_gpio_device);
-}
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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X common devices
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef _ATH79_DEV_COMMON_H
-#define _ATH79_DEV_COMMON_H
-
-void ath79_register_uart(void);
-void ath79_register_wdt(void);
-
-#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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X GPIO button support
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include "linux/init.h"
-#include "linux/slab.h"
-#include <linux/platform_device.h>
-
-#include "dev-gpio-buttons.h"
-
-void __init ath79_register_gpio_keys_polled(int id,
- unsigned poll_interval,
- unsigned nbuttons,
- struct gpio_keys_button *buttons)
-{
- struct platform_device *pdev;
- struct gpio_keys_platform_data pdata;
- struct gpio_keys_button *p;
- int err;
-
- p = kmemdup(buttons, nbuttons * sizeof(*p), GFP_KERNEL);
- if (!p)
- return;
-
- pdev = platform_device_alloc("gpio-keys-polled", id);
- if (!pdev)
- goto err_free_buttons;
-
- memset(&pdata, 0, sizeof(pdata));
- pdata.poll_interval = poll_interval;
- pdata.nbuttons = nbuttons;
- pdata.buttons = p;
-
- err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
- if (err)
- goto err_put_pdev;
-
- err = platform_device_add(pdev);
- if (err)
- goto err_put_pdev;
-
- return;
-
-err_put_pdev:
- platform_device_put(pdev);
-
-err_free_buttons:
- kfree(p);
-}
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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X GPIO button support
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef _ATH79_DEV_GPIO_BUTTONS_H
-#define _ATH79_DEV_GPIO_BUTTONS_H
-
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
-
-void ath79_register_gpio_keys_polled(int id,
- unsigned poll_interval,
- unsigned nbuttons,
- struct gpio_keys_button *buttons);
-
-#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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-
-#include "dev-leds-gpio.h"
-
-void __init ath79_register_leds_gpio(int id,
- unsigned num_leds,
- struct gpio_led *leds)
-{
- struct platform_device *pdev;
- struct gpio_led_platform_data pdata;
- struct gpio_led *p;
- int err;
-
- p = kmemdup(leds, num_leds * sizeof(*p), GFP_KERNEL);
- if (!p)
- return;
-
- pdev = platform_device_alloc("leds-gpio", id);
- if (!pdev)
- goto err_free_leds;
-
- memset(&pdata, 0, sizeof(pdata));
- pdata.num_leds = num_leds;
- pdata.leds = p;
-
- err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
- if (err)
- goto err_put_pdev;
-
- err = platform_device_add(pdev);
- if (err)
- goto err_put_pdev;
-
- return;
-
-err_put_pdev:
- platform_device_put(pdev);
-
-err_free_leds:
- kfree(p);
-}
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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef _ATH79_DEV_LEDS_GPIO_H
-#define _ATH79_DEV_LEDS_GPIO_H
-
-#include <linux/leds.h>
-
-void ath79_register_leds_gpio(int id,
- unsigned num_leds,
- struct gpio_led *leds);
-
-#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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X SPI controller device
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-#include "dev-spi.h"
-
-static struct resource ath79_spi_resources[] = {
- {
- .start = AR71XX_SPI_BASE,
- .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device ath79_spi_device = {
- .name = "ath79-spi",
- .id = -1,
- .resource = ath79_spi_resources,
- .num_resources = ARRAY_SIZE(ath79_spi_resources),
-};
-
-void __init ath79_register_spi(struct ath79_spi_platform_data *pdata,
- struct spi_board_info const *info,
- unsigned n)
-{
- spi_register_board_info(info, n);
- ath79_spi_device.dev.platform_data = pdata;
- platform_device_register(&ath79_spi_device);
-}
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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X SPI controller device
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef _ATH79_DEV_SPI_H
-#define _ATH79_DEV_SPI_H
-
-#include <linux/spi/spi.h>
-#include <linux/platform_data/spi-ath79.h>
-
-void ath79_register_spi(struct ath79_spi_platform_data *pdata,
- struct spi_board_info const *info,
- unsigned n);
-
-#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 @@
-/*
- * Atheros AR7XXX/AR9XXX USB Host Controller device
- *
- * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * Parts of this file are based on Atheros' 2.6.15 BSP
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/usb/ehci_pdriver.h>
-#include <linux/usb/ohci_pdriver.h>
-
-#include <asm/mach-ath79/ath79.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-#include "common.h"
-#include "dev-usb.h"
-
-static u64 ath79_usb_dmamask = DMA_BIT_MASK(32);
-
-static struct usb_ohci_pdata ath79_ohci_pdata = {
-};
-
-static struct usb_ehci_pdata ath79_ehci_pdata_v1 = {
- .has_synopsys_hc_bug = 1,
-};
-
-static struct usb_ehci_pdata ath79_ehci_pdata_v2 = {
- .caps_offset = 0x100,
- .has_tt = 1,
-};
-
-static void __init ath79_usb_register(const char *name, int id,
- unsigned long base, unsigned long size,
- int irq, const void *data,
- size_t data_size)
-{
- struct resource res[2];
- struct platform_device *pdev;
-
- memset(res, 0, sizeof(res));
-
- res[0].flags = IORESOURCE_MEM;
- res[0].start = base;
- res[0].end = base + size - 1;
-
- res[1].flags = IORESOURCE_IRQ;
- res[1].start = irq;
- res[1].end = irq;
-
- pdev = platform_device_register_resndata(NULL, name, id,
- res, ARRAY_SIZE(res),
- data, data_size);
-
- if (IS_ERR(pdev)) {
- pr_err("ath79: unable to register USB at %08lx, err=%d\n",
- base, (int) PTR_ERR(pdev));
- return;
- }
-
- pdev->dev.dma_mask = &ath79_usb_dmamask;
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-}
-
-#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \
- AR71XX_RESET_USB_PHY | \
- AR71XX_RESET_USB_OHCI_DLL)
-
-static void __init ath79_usb_setup(void)
-{
- void __iomem *usb_ctrl_base;
-
- ath79_device_reset_set(AR71XX_USB_RESET_MASK);
- mdelay(1000);
- ath79_device_reset_clear(AR71XX_USB_RESET_MASK);
-
- usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE);
-
- /* Turning on the Buff and Desc swap bits */
- __raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG);
-
- /* WAR for HW bug. Here it adjusts the duration between two SOFS */
- __raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
-
- iounmap(usb_ctrl_base);
-
- mdelay(900);
-
- ath79_usb_register("ohci-platform", -1,
- AR71XX_OHCI_BASE, AR71XX_OHCI_SIZE,
- ATH79_MISC_IRQ(6),
- &ath79_ohci_pdata, sizeof(ath79_ohci_pdata));
-
- ath79_usb_register("ehci-platform", -1,
- AR71XX_EHCI_BASE, AR71XX_EHCI_SIZE,
- ATH79_CPU_IRQ(3),
- &ath79_ehci_pdata_v1, sizeof(ath79_ehci_pdata_v1));
-}
-
-static void __init ar7240_usb_setup(void)
-{
- void __iomem *usb_ctrl_base;
-
- ath79_device_reset_clear(AR7240_RESET_OHCI_DLL);
- ath79_device_reset_set(AR7240_RESET_USB_HOST);
-
- mdelay(1000);
-
- ath79_device_reset_set(AR7240_RESET_OHCI_DLL);
- ath79_device_reset_clear(AR7240_RESET_USB_HOST);
-
- usb_ctrl_base = ioremap(AR7240_USB_CTRL_BASE, AR7240_USB_CTRL_SIZE);
-
- /* WAR for HW bug. Here it adjusts the duration between two SOFS */
- __raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
-
- iounmap(usb_ctrl_base);
-
- ath79_usb_register("ohci-platform", -1,
- AR7240_OHCI_BASE, AR7240_OHCI_SIZE,
- ATH79_CPU_IRQ(3),
- &ath79_ohci_pdata, sizeof(ath79_ohci_pdata));
-}
-
-static void __init ar724x_usb_setup(void)
-{
- ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE);
- mdelay(10);
-
- ath79_device_reset_clear(AR724X_RESET_USB_HOST);
- mdelay(10);
-
- ath79_device_reset_clear(AR724X_RESET_USB_PHY);
- mdelay(10);
-
- ath79_usb_register("ehci-platform", -1,
- AR724X_EHCI_BASE, AR724X_EHCI_SIZE,
- ATH79_CPU_IRQ(3),
- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
-}
-
-static void __init ar913x_usb_setup(void)
-{
- ath79_device_reset_set(AR913X_RESET_USBSUS_OVERRIDE);
- mdelay(10);
-
- ath79_device_reset_clear(AR913X_RESET_USB_HOST);
- mdelay(10);
-
- ath79_device_reset_clear(AR913X_RESET_USB_PHY);
- mdelay(10);
-
- ath79_usb_register("ehci-platform", -1,
- AR913X_EHCI_BASE, AR913X_EHCI_SIZE,
- ATH79_CPU_IRQ(3),
- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
-}
-
-static void __init ar933x_usb_setup(void)
-{
- ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE);
- mdelay(10);
-
- ath79_device_reset_clear(AR933X_RESET_USB_HOST);
- mdelay(10);
-
- ath79_device_reset_clear(AR933X_RESET_USB_PHY);
- mdelay(10);
-
- ath79_usb_register("ehci-platform", -1,
- AR933X_EHCI_BASE, AR933X_EHCI_SIZE,
- ATH79_CPU_IRQ(3),
- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
-}
-
-static void __init ar934x_usb_setup(void)
-{
- u32 bootstrap;
-
- bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
- if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
- return;
-
- ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE);
- udelay(1000);
-
- ath79_device_reset_clear(AR934X_RESET_USB_PHY);
- udelay(1000);
-
- ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG);
- udelay(1000);
-
- ath79_device_reset_clear(AR934X_RESET_USB_HOST);
- udelay(1000);
-
- ath79_usb_register("ehci-platform", -1,
- AR934X_EHCI_BASE, AR934X_EHCI_SIZE,
- ATH79_CPU_IRQ(3),
- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
-}
-
-static void __init qca955x_usb_setup(void)
-{
- ath79_usb_register("ehci-platform", 0,
- QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE,
- ATH79_IP3_IRQ(0),
- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
-
- ath79_usb_register("ehci-platform", 1,
- QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE,
- ATH79_IP3_IRQ(1),
- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
-}
-
-void __init ath79_register_usb(void)
-{
- if (soc_is_ar71xx())
- ath79_usb_setup();
- else if (soc_is_ar7240())
- ar7240_usb_setup();
- else if (soc_is_ar7241() || soc_is_ar7242())
- ar724x_usb_setup();
- else if (soc_is_ar913x())
- ar913x_usb_setup();
- else if (soc_is_ar933x())
- ar933x_usb_setup();
- else if (soc_is_ar934x())
- ar934x_usb_setup();
- else if (soc_is_qca955x())
- qca955x_usb_setup();
- else
- BUG();
-}
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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X USB Host Controller support
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef _ATH79_DEV_USB_H
-#define _ATH79_DEV_USB_H
-
-void ath79_register_usb(void);
-
-#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 @@
-/*
- * Atheros AR913X/AR933X SoC built-in WMAC device support
- *
- * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
- * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/ath9k_platform.h>
-
-#include <asm/mach-ath79/ath79.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-#include "dev-wmac.h"
-
-static struct ath9k_platform_data ath79_wmac_data;
-
-static struct resource ath79_wmac_resources[] = {
- {
- /* .start and .end fields are filled dynamically */
- .flags = IORESOURCE_MEM,
- }, {
- /* .start and .end fields are filled dynamically */
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device ath79_wmac_device = {
- .name = "ath9k",
- .id = -1,
- .resource = ath79_wmac_resources,
- .num_resources = ARRAY_SIZE(ath79_wmac_resources),
- .dev = {
- .platform_data = &ath79_wmac_data,
- },
-};
-
-static void __init ar913x_wmac_setup(void)
-{
- /* reset the WMAC */
- ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
- mdelay(10);
-
- ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
- mdelay(10);
-
- ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
- ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
- ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2);
- ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2);
-}
-
-
-static int ar933x_wmac_reset(void)
-{
- ath79_device_reset_set(AR933X_RESET_WMAC);
- ath79_device_reset_clear(AR933X_RESET_WMAC);
-
- return 0;
-}
-
-static int ar933x_r1_get_wmac_revision(void)
-{
- return ath79_soc_rev;
-}
-
-static void __init ar933x_wmac_setup(void)
-{
- u32 t;
-
- ar933x_wmac_reset();
-
- ath79_wmac_device.name = "ar933x_wmac";
-
- ath79_wmac_resources[0].start = AR933X_WMAC_BASE;
- ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
- ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2);
- ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2);
-
- t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
- if (t & AR933X_BOOTSTRAP_REF_CLK_40)
- ath79_wmac_data.is_clk_25mhz = false;
- else
- ath79_wmac_data.is_clk_25mhz = true;
-
- if (ath79_soc_rev == 1)
- ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision;
-
- ath79_wmac_data.external_reset = ar933x_wmac_reset;
-}
-
-static void ar934x_wmac_setup(void)
-{
- u32 t;
-
- ath79_wmac_device.name = "ar934x_wmac";
-
- ath79_wmac_resources[0].start = AR934X_WMAC_BASE;
- ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1;
- ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
- ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1);
-
- t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
- if (t & AR934X_BOOTSTRAP_REF_CLK_40)
- ath79_wmac_data.is_clk_25mhz = false;
- else
- ath79_wmac_data.is_clk_25mhz = true;
-}
-
-static void qca955x_wmac_setup(void)
-{
- u32 t;
-
- ath79_wmac_device.name = "qca955x_wmac";
-
- ath79_wmac_resources[0].start = QCA955X_WMAC_BASE;
- ath79_wmac_resources[0].end = QCA955X_WMAC_BASE + QCA955X_WMAC_SIZE - 1;
- ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
- ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1);
-
- t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
- if (t & QCA955X_BOOTSTRAP_REF_CLK_40)
- ath79_wmac_data.is_clk_25mhz = false;
- else
- ath79_wmac_data.is_clk_25mhz = true;
-}
-
-void __init ath79_register_wmac(u8 *cal_data)
-{
- if (soc_is_ar913x())
- ar913x_wmac_setup();
- else if (soc_is_ar933x())
- ar933x_wmac_setup();
- else if (soc_is_ar934x())
- ar934x_wmac_setup();
- else if (soc_is_qca955x())
- qca955x_wmac_setup();
- else
- BUG();
-
- if (cal_data)
- memcpy(ath79_wmac_data.eeprom_data, cal_data,
- sizeof(ath79_wmac_data.eeprom_data));
-
- platform_device_register(&ath79_wmac_device);
-}
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 @@
-/*
- * Atheros AR913X/AR933X SoC built-in WMAC device support
- *
- * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef _ATH79_DEV_WMAC_H
-#define _ATH79_DEV_WMAC_H
-
-void ath79_register_wmac(u8 *cal_data);
-
-#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 @@
-/*
- * Atheros AR71xx/AR724x/AR913x specific interrupt handling
- *
- * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
- * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irqchip.h>
-#include <linux/of_irq.h>
-
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-
-#include <asm/mach-ath79/ath79.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-#include "common.h"
-#include "machtypes.h"
-
-
-static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
-{
- u32 status;
-
- status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
-
- if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {
- ath79_ddr_wb_flush(3);
- generic_handle_irq(ATH79_IP2_IRQ(0));
- } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) {
- ath79_ddr_wb_flush(4);
- generic_handle_irq(ATH79_IP2_IRQ(1));
- } else {
- spurious_interrupt();
- }
-}
-
-static void ar934x_ip2_irq_init(void)
-{
- int i;
-
- for (i = ATH79_IP2_IRQ_BASE;
- i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip,
- handle_level_irq);
-
- irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch);
-}
-
-static void qca955x_ip2_irq_dispatch(struct irq_desc *desc)
-{
- u32 status;
-
- status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
- status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL;
-
- if (status == 0) {
- spurious_interrupt();
- return;
- }
-
- if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) {
- /* TODO: flush DDR? */
- generic_handle_irq(ATH79_IP2_IRQ(0));
- }
-
- if (status & QCA955X_EXT_INT_WMAC_ALL) {
- /* TODO: flush DDR? */
- generic_handle_irq(ATH79_IP2_IRQ(1));
- }
-}
-
-static void qca955x_ip3_irq_dispatch(struct irq_desc *desc)
-{
- u32 status;
-
- status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
- status &= QCA955X_EXT_INT_PCIE_RC2_ALL |
- QCA955X_EXT_INT_USB1 |
- QCA955X_EXT_INT_USB2;
-
- if (status == 0) {
- spurious_interrupt();
- return;
- }
-
- if (status & QCA955X_EXT_INT_USB1) {
- /* TODO: flush DDR? */
- generic_handle_irq(ATH79_IP3_IRQ(0));
- }
-
- if (status & QCA955X_EXT_INT_USB2) {
- /* TODO: flush DDR? */
- generic_handle_irq(ATH79_IP3_IRQ(1));
- }
-
- if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) {
- /* TODO: flush DDR? */
- generic_handle_irq(ATH79_IP3_IRQ(2));
- }
-}
-
-static void qca955x_irq_init(void)
-{
- int i;
-
- for (i = ATH79_IP2_IRQ_BASE;
- i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip,
- handle_level_irq);
-
- irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch);
-
- for (i = ATH79_IP3_IRQ_BASE;
- i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip,
- handle_level_irq);
-
- irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
-}
-
-void __init arch_init_irq(void)
-{
- unsigned irq_wb_chan2 = -1;
- unsigned irq_wb_chan3 = -1;
- bool misc_is_ar71xx;
-
- if (mips_machtype == ATH79_MACH_GENERIC_OF) {
- irqchip_init();
- return;
- }
-
- if (soc_is_ar71xx() || soc_is_ar724x() ||
- soc_is_ar913x() || soc_is_ar933x()) {
- irq_wb_chan2 = 3;
- irq_wb_chan3 = 2;
- } else if (soc_is_ar934x()) {
- irq_wb_chan3 = 2;
- }
-
- ath79_cpu_irq_init(irq_wb_chan2, irq_wb_chan3);
-
- if (soc_is_ar71xx() || soc_is_ar913x())
- misc_is_ar71xx = true;
- else if (soc_is_ar724x() ||
- soc_is_ar933x() ||
- soc_is_ar934x() ||
- soc_is_qca955x())
- misc_is_ar71xx = false;
- else
- BUG();
- ath79_misc_irq_init(
- ath79_reset_base + AR71XX_RESET_REG_MISC_INT_STATUS,
- ATH79_CPU_IRQ(6), ATH79_MISC_IRQ_BASE, misc_is_ar71xx);
-
- if (soc_is_ar934x())
- ar934x_ip2_irq_init();
- else if (soc_is_qca955x())
- qca955x_irq_init();
-}
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 @@
-/*
- * Atheros AP121 board support
- *
- * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include "machtypes.h"
-#include "dev-gpio-buttons.h"
-#include "dev-leds-gpio.h"
-#include "dev-spi.h"
-#include "dev-usb.h"
-#include "dev-wmac.h"
-
-#define AP121_GPIO_LED_WLAN 0
-#define AP121_GPIO_LED_USB 1
-
-#define AP121_GPIO_BTN_JUMPSTART 11
-#define AP121_GPIO_BTN_RESET 12
-
-#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */
-#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL)
-
-#define AP121_CAL_DATA_ADDR 0x1fff1000
-
-static struct gpio_led ap121_leds_gpio[] __initdata = {
- {
- .name = "ap121:green:usb",
- .gpio = AP121_GPIO_LED_USB,
- .active_low = 0,
- },
- {
- .name = "ap121:green:wlan",
- .gpio = AP121_GPIO_LED_WLAN,
- .active_low = 0,
- },
-};
-
-static struct gpio_keys_button ap121_gpio_keys[] __initdata = {
- {
- .desc = "jumpstart button",
- .type = EV_KEY,
- .code = KEY_WPS_BUTTON,
- .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
- .gpio = AP121_GPIO_BTN_JUMPSTART,
- .active_low = 1,
- },
- {
- .desc = "reset button",
- .type = EV_KEY,
- .code = KEY_RESTART,
- .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
- .gpio = AP121_GPIO_BTN_RESET,
- .active_low = 1,
- }
-};
-
-static struct spi_board_info ap121_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "mx25l1606e",
- }
-};
-
-static struct ath79_spi_platform_data ap121_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
-};
-
-static void __init ap121_setup(void)
-{
- u8 *cal_data = (u8 *) KSEG1ADDR(AP121_CAL_DATA_ADDR);
-
- ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio),
- ap121_leds_gpio);
- ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL,
- ARRAY_SIZE(ap121_gpio_keys),
- ap121_gpio_keys);
-
- ath79_register_spi(&ap121_spi_data, ap121_spi_info,
- ARRAY_SIZE(ap121_spi_info));
- ath79_register_usb();
- ath79_register_wmac(cal_data);
-}
-
-MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board",
- 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 @@
-/*
- * Qualcomm Atheros AP136 reference board support
- *
- * Copyright (c) 2012 Qualcomm Atheros
- * Copyright (c) 2012-2013 Gabor Juhos <juhosg@openwrt.org>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include <linux/pci.h>
-#include <linux/ath9k_platform.h>
-
-#include "machtypes.h"
-#include "dev-gpio-buttons.h"
-#include "dev-leds-gpio.h"
-#include "dev-spi.h"
-#include "dev-usb.h"
-#include "dev-wmac.h"
-#include "pci.h"
-
-#define AP136_GPIO_LED_STATUS_RED 14
-#define AP136_GPIO_LED_STATUS_GREEN 19
-#define AP136_GPIO_LED_USB 4
-#define AP136_GPIO_LED_WLAN_2G 13
-#define AP136_GPIO_LED_WLAN_5G 12
-#define AP136_GPIO_LED_WPS_RED 15
-#define AP136_GPIO_LED_WPS_GREEN 20
-
-#define AP136_GPIO_BTN_WPS 16
-#define AP136_GPIO_BTN_RFKILL 21
-
-#define AP136_KEYS_POLL_INTERVAL 20 /* msecs */
-#define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL)
-
-#define AP136_WMAC_CALDATA_OFFSET 0x1000
-#define AP136_PCIE_CALDATA_OFFSET 0x5000
-
-static struct gpio_led ap136_leds_gpio[] __initdata = {
- {
- .name = "qca:green:status",
- .gpio = AP136_GPIO_LED_STATUS_GREEN,
- .active_low = 1,
- },
- {
- .name = "qca:red:status",
- .gpio = AP136_GPIO_LED_STATUS_RED,
- .active_low = 1,
- },
- {
- .name = "qca:green:wps",
- .gpio = AP136_GPIO_LED_WPS_GREEN,
- .active_low = 1,
- },
- {
- .name = "qca:red:wps",
- .gpio = AP136_GPIO_LED_WPS_RED,
- .active_low = 1,
- },
- {
- .name = "qca:red:wlan-2g",
- .gpio = AP136_GPIO_LED_WLAN_2G,
- .active_low = 1,
- },
- {
- .name = "qca:red:usb",
- .gpio = AP136_GPIO_LED_USB,
- .active_low = 1,
- }
-};
-
-static struct gpio_keys_button ap136_gpio_keys[] __initdata = {
- {
- .desc = "WPS button",
- .type = EV_KEY,
- .code = KEY_WPS_BUTTON,
- .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL,
- .gpio = AP136_GPIO_BTN_WPS,
- .active_low = 1,
- },
- {
- .desc = "RFKILL button",
- .type = EV_KEY,
- .code = KEY_RFKILL,
- .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL,
- .gpio = AP136_GPIO_BTN_RFKILL,
- .active_low = 1,
- },
-};
-
-static struct spi_board_info ap136_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "mx25l6405d",
- }
-};
-
-static struct ath79_spi_platform_data ap136_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
-};
-
-#ifdef CONFIG_PCI
-static struct ath9k_platform_data ap136_ath9k_data;
-
-static int ap136_pci_plat_dev_init(struct pci_dev *dev)
-{
- if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0)
- dev->dev.platform_data = &ap136_ath9k_data;
-
- return 0;
-}
-
-static void __init ap136_pci_init(u8 *eeprom)
-{
- memcpy(ap136_ath9k_data.eeprom_data, eeprom,
- sizeof(ap136_ath9k_data.eeprom_data));
-
- ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init);
- ath79_register_pci();
-}
-#else
-static inline void ap136_pci_init(u8 *eeprom) {}
-#endif /* CONFIG_PCI */
-
-static void __init ap136_setup(void)
-{
- u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
-
- ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio),
- ap136_leds_gpio);
- ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL,
- ARRAY_SIZE(ap136_gpio_keys),
- ap136_gpio_keys);
- ath79_register_spi(&ap136_spi_data, ap136_spi_info,
- ARRAY_SIZE(ap136_spi_info));
- ath79_register_usb();
- ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET);
- ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET);
-}
-
-MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010",
- "Atheros AP136-010 reference board",
- 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 @@
-/*
- * Atheros AP81 board support
- *
- * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include "machtypes.h"
-#include "dev-wmac.h"
-#include "dev-gpio-buttons.h"
-#include "dev-leds-gpio.h"
-#include "dev-spi.h"
-#include "dev-usb.h"
-
-#define AP81_GPIO_LED_STATUS 1
-#define AP81_GPIO_LED_AOSS 3
-#define AP81_GPIO_LED_WLAN 6
-#define AP81_GPIO_LED_POWER 14
-
-#define AP81_GPIO_BTN_SW4 12
-#define AP81_GPIO_BTN_SW1 21
-
-#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */
-#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL)
-
-#define AP81_CAL_DATA_ADDR 0x1fff1000
-
-static struct gpio_led ap81_leds_gpio[] __initdata = {
- {
- .name = "ap81:green:status",
- .gpio = AP81_GPIO_LED_STATUS,
- .active_low = 1,
- }, {
- .name = "ap81:amber:aoss",
- .gpio = AP81_GPIO_LED_AOSS,
- .active_low = 1,
- }, {
- .name = "ap81:green:wlan",
- .gpio = AP81_GPIO_LED_WLAN,
- .active_low = 1,
- }, {
- .name = "ap81:green:power",
- .gpio = AP81_GPIO_LED_POWER,
- .active_low = 1,
- }
-};
-
-static struct gpio_keys_button ap81_gpio_keys[] __initdata = {
- {
- .desc = "sw1",
- .type = EV_KEY,
- .code = BTN_0,
- .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
- .gpio = AP81_GPIO_BTN_SW1,
- .active_low = 1,
- } , {
- .desc = "sw4",
- .type = EV_KEY,
- .code = BTN_1,
- .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
- .gpio = AP81_GPIO_BTN_SW4,
- .active_low = 1,
- }
-};
-
-static struct spi_board_info ap81_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "m25p64",
- }
-};
-
-static struct ath79_spi_platform_data ap81_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
-};
-
-static void __init ap81_setup(void)
-{
- u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR);
-
- ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
- ap81_leds_gpio);
- ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
- ARRAY_SIZE(ap81_gpio_keys),
- ap81_gpio_keys);
- ath79_register_spi(&ap81_spi_data, ap81_spi_info,
- ARRAY_SIZE(ap81_spi_info));
- ath79_register_wmac(cal_data);
- ath79_register_usb();
-}
-
-MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
- 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 @@
-/*
- * Atheros DB120 reference board support
- *
- * Copyright (c) 2011 Qualcomm Atheros
- * Copyright (c) 2011 Gabor Juhos <juhosg@openwrt.org>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include <linux/pci.h>
-#include <linux/ath9k_platform.h>
-
-#include "machtypes.h"
-#include "dev-gpio-buttons.h"
-#include "dev-leds-gpio.h"
-#include "dev-spi.h"
-#include "dev-usb.h"
-#include "dev-wmac.h"
-#include "pci.h"
-
-#define DB120_GPIO_LED_WLAN_5G 12
-#define DB120_GPIO_LED_WLAN_2G 13
-#define DB120_GPIO_LED_STATUS 14
-#define DB120_GPIO_LED_WPS 15
-
-#define DB120_GPIO_BTN_WPS 16
-
-#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */
-#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL)
-
-#define DB120_WMAC_CALDATA_OFFSET 0x1000
-#define DB120_PCIE_CALDATA_OFFSET 0x5000
-
-static struct gpio_led db120_leds_gpio[] __initdata = {
- {
- .name = "db120:green:status",
- .gpio = DB120_GPIO_LED_STATUS,
- .active_low = 1,
- },
- {
- .name = "db120:green:wps",
- .gpio = DB120_GPIO_LED_WPS,
- .active_low = 1,
- },
- {
- .name = "db120:green:wlan-5g",
- .gpio = DB120_GPIO_LED_WLAN_5G,
- .active_low = 1,
- },
- {
- .name = "db120:green:wlan-2g",
- .gpio = DB120_GPIO_LED_WLAN_2G,
- .active_low = 1,
- },
-};
-
-static struct gpio_keys_button db120_gpio_keys[] __initdata = {
- {
- .desc = "WPS button",
- .type = EV_KEY,
- .code = KEY_WPS_BUTTON,
- .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL,
- .gpio = DB120_GPIO_BTN_WPS,
- .active_low = 1,
- },
-};
-
-static struct spi_board_info db120_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "s25sl064a",
- }
-};
-
-static struct ath79_spi_platform_data db120_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
-};
-
-#ifdef CONFIG_PCI
-static struct ath9k_platform_data db120_ath9k_data;
-
-static int db120_pci_plat_dev_init(struct pci_dev *dev)
-{
- switch (PCI_SLOT(dev->devfn)) {
- case 0:
- dev->dev.platform_data = &db120_ath9k_data;
- break;
- }
-
- return 0;
-}
-
-static void __init db120_pci_init(u8 *eeprom)
-{
- memcpy(db120_ath9k_data.eeprom_data, eeprom,
- sizeof(db120_ath9k_data.eeprom_data));
-
- ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init);
- ath79_register_pci();
-}
-#else
-static inline void db120_pci_init(u8 *eeprom) {}
-#endif /* CONFIG_PCI */
-
-static void __init db120_setup(void)
-{
- u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
-
- ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio),
- db120_leds_gpio);
- ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL,
- ARRAY_SIZE(db120_gpio_keys),
- db120_gpio_keys);
- ath79_register_spi(&db120_spi_data, db120_spi_info,
- ARRAY_SIZE(db120_spi_info));
- ath79_register_usb();
- ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET);
- db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
-}
-
-MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board",
- 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 @@
-/*
- * Atheros PB44 reference board support
- *
- * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/gpio/machine.h>
-#include <linux/platform_data/pcf857x.h>
-
-#include "machtypes.h"
-#include "dev-gpio-buttons.h"
-#include "dev-leds-gpio.h"
-#include "dev-spi.h"
-#include "dev-usb.h"
-#include "pci.h"
-
-#define PB44_GPIO_I2C_SCL 0
-#define PB44_GPIO_I2C_SDA 1
-
-#define PB44_GPIO_EXP_BASE 16
-#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6)
-#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8)
-#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9)
-#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + 10)
-
-#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */
-#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL)
-
-static struct gpiod_lookup_table pb44_i2c_gpiod_table = {
- .dev_id = "i2c-gpio.0",
- .table = {
- GPIO_LOOKUP_IDX("ath79-gpio", PB44_GPIO_I2C_SDA,
- NULL, 0, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
- GPIO_LOOKUP_IDX("ath79-gpio", PB44_GPIO_I2C_SCL,
- NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
- },
-};
-
-static struct platform_device pb44_i2c_gpio_device = {
- .name = "i2c-gpio",
- .id = 0,
- .dev = {
- .platform_data = NULL,
- }
-};
-
-static struct pcf857x_platform_data pb44_pcf857x_data = {
- .gpio_base = PB44_GPIO_EXP_BASE,
-};
-
-static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
- {
- I2C_BOARD_INFO("pcf8575", 0x20),
- .platform_data = &pb44_pcf857x_data,
- },
-};
-
-static struct gpio_led pb44_leds_gpio[] __initdata = {
- {
- .name = "pb44:amber:jump1",
- .gpio = PB44_GPIO_LED_JUMP1,
- .active_low = 1,
- }, {
- .name = "pb44:green:jump2",
- .gpio = PB44_GPIO_LED_JUMP2,
- .active_low = 1,
- },
-};
-
-static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
- {
- .desc = "soft_reset",
- .type = EV_KEY,
- .code = KEY_RESTART,
- .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
- .gpio = PB44_GPIO_SW_RESET,
- .active_low = 1,
- } , {
- .desc = "jumpstart",
- .type = EV_KEY,
- .code = KEY_WPS_BUTTON,
- .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
- .gpio = PB44_GPIO_SW_JUMP,
- .active_low = 1,
- }
-};
-
-static struct spi_board_info pb44_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "m25p64",
- },
-};
-
-static struct ath79_spi_platform_data pb44_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
-};
-
-static void __init pb44_init(void)
-{
- gpiod_add_lookup_table(&pb44_i2c_gpiod_table);
- i2c_register_board_info(0, pb44_i2c_board_info,
- ARRAY_SIZE(pb44_i2c_board_info));
- platform_device_register(&pb44_i2c_gpio_device);
-
- ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
- pb44_leds_gpio);
- ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
- ARRAY_SIZE(pb44_gpio_keys),
- pb44_gpio_keys);
- ath79_register_spi(&pb44_spi_data, pb44_spi_info,
- ARRAY_SIZE(pb44_spi_info));
- ath79_register_usb();
- ath79_register_pci();
-}
-
-MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
- 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 @@
-/*
- * Ubiquiti Networks XM (rev 1.0) board support
- *
- * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
- *
- * Derived from: mach-pb44.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/ath9k_platform.h>
-
-#include <asm/mach-ath79/irq.h>
-
-#include "machtypes.h"
-#include "dev-gpio-buttons.h"
-#include "dev-leds-gpio.h"
-#include "dev-spi.h"
-#include "pci.h"
-
-#define UBNT_XM_GPIO_LED_L1 0
-#define UBNT_XM_GPIO_LED_L2 1
-#define UBNT_XM_GPIO_LED_L3 11
-#define UBNT_XM_GPIO_LED_L4 7
-
-#define UBNT_XM_GPIO_BTN_RESET 12
-
-#define UBNT_XM_KEYS_POLL_INTERVAL 20
-#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL)
-
-#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000)
-
-static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
- {
- .name = "ubnt-xm:red:link1",
- .gpio = UBNT_XM_GPIO_LED_L1,
- .active_low = 0,
- }, {
- .name = "ubnt-xm:orange:link2",
- .gpio = UBNT_XM_GPIO_LED_L2,
- .active_low = 0,
- }, {
- .name = "ubnt-xm:green:link3",
- .gpio = UBNT_XM_GPIO_LED_L3,
- .active_low = 0,
- }, {
- .name = "ubnt-xm:green:link4",
- .gpio = UBNT_XM_GPIO_LED_L4,
- .active_low = 0,
- },
-};
-
-static struct gpio_keys_button ubnt_xm_gpio_keys[] __initdata = {
- {
- .desc = "reset",
- .type = EV_KEY,
- .code = KEY_RESTART,
- .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL,
- .gpio = UBNT_XM_GPIO_BTN_RESET,
- .active_low = 1,
- }
-};
-
-static struct spi_board_info ubnt_xm_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "mx25l6405d",
- }
-};
-
-static struct ath79_spi_platform_data ubnt_xm_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
-};
-
-#ifdef CONFIG_PCI
-static struct ath9k_platform_data ubnt_xm_eeprom_data;
-
-static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
-{
- switch (PCI_SLOT(dev->devfn)) {
- case 0:
- dev->dev.platform_data = &ubnt_xm_eeprom_data;
- break;
- }
-
- return 0;
-}
-
-static void __init ubnt_xm_pci_init(void)
-{
- memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
- sizeof(ubnt_xm_eeprom_data.eeprom_data));
-
- ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
- ath79_register_pci();
-}
-#else
-static inline void ubnt_xm_pci_init(void) {}
-#endif /* CONFIG_PCI */
-
-static void __init ubnt_xm_init(void)
-{
- ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio),
- ubnt_xm_leds_gpio);
-
- ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
- ARRAY_SIZE(ubnt_xm_gpio_keys),
- ubnt_xm_gpio_keys);
-
- ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info,
- ARRAY_SIZE(ubnt_xm_spi_info));
-
- ubnt_xm_pci_init();
-}
-
-MIPS_MACHINE(ATH79_MACH_UBNT_XM,
- "UBNT-XM",
- "Ubiquiti Networks XM (rev 1.0) board",
- 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 @@
-/*
- * Atheros AR71XX/AR724X/AR913X machine type definitions
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef _ATH79_MACHTYPE_H
-#define _ATH79_MACHTYPE_H
-
-#include <asm/mips_machine.h>
-
-enum ath79_mach_type {
- ATH79_MACH_GENERIC_OF = -1, /* Device tree board */
- ATH79_MACH_GENERIC = 0,
- ATH79_MACH_AP121, /* Atheros AP121 reference board */
- ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */
- ATH79_MACH_AP81, /* Atheros AP81 reference board */
- ATH79_MACH_DB120, /* Atheros DB120 reference board */
- ATH79_MACH_PB44, /* Atheros PB44 reference board */
- ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */
-};
-
-#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 @@
-/*
- * Atheros AR71XX/AR724X specific PCI setup code
- *
- * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
- * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * Parts of this file are based on Atheros' 2.6.15 BSP
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/resource.h>
-#include <linux/platform_device.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-#include <asm/mach-ath79/ath79.h>
-#include <asm/mach-ath79/irq.h>
-#include "pci.h"
-
-static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
-static const struct ath79_pci_irq *ath79_pci_irq_map;
-static unsigned ath79_pci_nr_irqs;
-
-static const struct ath79_pci_irq ar71xx_pci_irq_map[] = {
- {
- .slot = 17,
- .pin = 1,
- .irq = ATH79_PCI_IRQ(0),
- }, {
- .slot = 18,
- .pin = 1,
- .irq = ATH79_PCI_IRQ(1),
- }, {
- .slot = 19,
- .pin = 1,
- .irq = ATH79_PCI_IRQ(2),
- }
-};
-
-static const struct ath79_pci_irq ar724x_pci_irq_map[] = {
- {
- .slot = 0,
- .pin = 1,
- .irq = ATH79_PCI_IRQ(0),
- }
-};
-
-static const struct ath79_pci_irq qca955x_pci_irq_map[] = {
- {
- .bus = 0,
- .slot = 0,
- .pin = 1,
- .irq = ATH79_PCI_IRQ(0),
- },
- {
- .bus = 1,
- .slot = 0,
- .pin = 1,
- .irq = ATH79_PCI_IRQ(1),
- },
-};
-
-int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
-{
- int irq = -1;
- int i;
-
- if (ath79_pci_nr_irqs == 0 ||
- ath79_pci_irq_map == NULL) {
- if (soc_is_ar71xx()) {
- ath79_pci_irq_map = ar71xx_pci_irq_map;
- ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map);
- } else if (soc_is_ar724x() ||
- soc_is_ar9342() ||
- soc_is_ar9344()) {
- ath79_pci_irq_map = ar724x_pci_irq_map;
- ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map);
- } else if (soc_is_qca955x()) {
- ath79_pci_irq_map = qca955x_pci_irq_map;
- ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map);
- } else {
- pr_crit("pci %s: invalid irq map\n",
- pci_name((struct pci_dev *) dev));
- return irq;
- }
- }
-
- for (i = 0; i < ath79_pci_nr_irqs; i++) {
- const struct ath79_pci_irq *entry;
-
- entry = &ath79_pci_irq_map[i];
- if (entry->bus == dev->bus->number &&
- entry->slot == slot &&
- entry->pin == pin) {
- irq = entry->irq;
- break;
- }
- }
-
- if (irq < 0)
- pr_crit("pci %s: no irq found for pin %u\n",
- pci_name((struct pci_dev *) dev), pin);
- else
- pr_info("pci %s: using irq %d for pin %u\n",
- pci_name((struct pci_dev *) dev), irq, pin);
-
- return irq;
-}
-
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
- if (ath79_pci_plat_dev_init)
- return ath79_pci_plat_dev_init(dev);
-
- return 0;
-}
-
-void __init ath79_pci_set_irq_map(unsigned nr_irqs,
- const struct ath79_pci_irq *map)
-{
- ath79_pci_nr_irqs = nr_irqs;
- ath79_pci_irq_map = map;
-}
-
-void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
-{
- ath79_pci_plat_dev_init = func;
-}
-
-static struct platform_device *
-ath79_register_pci_ar71xx(void)
-{
- struct platform_device *pdev;
- struct resource res[4];
-
- memset(res, 0, sizeof(res));
-
- res[0].name = "cfg_base";
- res[0].flags = IORESOURCE_MEM;
- res[0].start = AR71XX_PCI_CFG_BASE;
- res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1;
-
- res[1].flags = IORESOURCE_IRQ;
- res[1].start = ATH79_CPU_IRQ(2);
- res[1].end = ATH79_CPU_IRQ(2);
-
- res[2].name = "io_base";
- res[2].flags = IORESOURCE_IO;
- res[2].start = 0;
- res[2].end = 0;
-
- res[3].name = "mem_base";
- res[3].flags = IORESOURCE_MEM;
- res[3].start = AR71XX_PCI_MEM_BASE;
- res[3].end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1;
-
- pdev = platform_device_register_simple("ar71xx-pci", -1,
- res, ARRAY_SIZE(res));
- return pdev;
-}
-
-static struct platform_device *
-ath79_register_pci_ar724x(int id,
- unsigned long cfg_base,
- unsigned long ctrl_base,
- unsigned long crp_base,
- unsigned long mem_base,
- unsigned long mem_size,
- unsigned long io_base,
- int irq)
-{
- struct platform_device *pdev;
- struct resource res[6];
-
- memset(res, 0, sizeof(res));
-
- res[0].name = "cfg_base";
- res[0].flags = IORESOURCE_MEM;
- res[0].start = cfg_base;
- res[0].end = cfg_base + AR724X_PCI_CFG_SIZE - 1;
-
- res[1].name = "ctrl_base";
- res[1].flags = IORESOURCE_MEM;
- res[1].start = ctrl_base;
- res[1].end = ctrl_base + AR724X_PCI_CTRL_SIZE - 1;
-
- res[2].flags = IORESOURCE_IRQ;
- res[2].start = irq;
- res[2].end = irq;
-
- res[3].name = "mem_base";
- res[3].flags = IORESOURCE_MEM;
- res[3].start = mem_base;
- res[3].end = mem_base + mem_size - 1;
-
- res[4].name = "io_base";
- res[4].flags = IORESOURCE_IO;
- res[4].start = io_base;
- res[4].end = io_base;
-
- res[5].name = "crp_base";
- res[5].flags = IORESOURCE_MEM;
- res[5].start = crp_base;
- res[5].end = crp_base + AR724X_PCI_CRP_SIZE - 1;
-
- pdev = platform_device_register_simple("ar724x-pci", id,
- res, ARRAY_SIZE(res));
- return pdev;
-}
-
-int __init ath79_register_pci(void)
-{
- struct platform_device *pdev = NULL;
-
- if (soc_is_ar71xx()) {
- pdev = ath79_register_pci_ar71xx();
- } else if (soc_is_ar724x()) {
- pdev = ath79_register_pci_ar724x(-1,
- AR724X_PCI_CFG_BASE,
- AR724X_PCI_CTRL_BASE,
- AR724X_PCI_CRP_BASE,
- AR724X_PCI_MEM_BASE,
- AR724X_PCI_MEM_SIZE,
- 0,
- ATH79_CPU_IRQ(2));
- } else if (soc_is_ar9342() ||
- soc_is_ar9344()) {
- u32 bootstrap;
-
- bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
- if ((bootstrap & AR934X_BOOTSTRAP_PCIE_RC) == 0)
- return -ENODEV;
-
- pdev = ath79_register_pci_ar724x(-1,
- AR724X_PCI_CFG_BASE,
- AR724X_PCI_CTRL_BASE,
- AR724X_PCI_CRP_BASE,
- AR724X_PCI_MEM_BASE,
- AR724X_PCI_MEM_SIZE,
- 0,
- ATH79_IP2_IRQ(0));
- } else if (soc_is_qca9558()) {
- pdev = ath79_register_pci_ar724x(0,
- QCA955X_PCI_CFG_BASE0,
- QCA955X_PCI_CTRL_BASE0,
- QCA955X_PCI_CRP_BASE0,
- QCA955X_PCI_MEM_BASE0,
- QCA955X_PCI_MEM_SIZE,
- 0,
- ATH79_IP2_IRQ(0));
-
- pdev = ath79_register_pci_ar724x(1,
- QCA955X_PCI_CFG_BASE1,
- QCA955X_PCI_CTRL_BASE1,
- QCA955X_PCI_CRP_BASE1,
- QCA955X_PCI_MEM_BASE1,
- QCA955X_PCI_MEM_SIZE,
- 1,
- ATH79_IP3_IRQ(2));
- } else {
- /* No PCI support */
- return -ENODEV;
- }
-
- if (!pdev)
- pr_err("unable to register PCI controller device\n");
-
- return pdev ? 0 : -ENODEV;
-}
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 @@
-/*
- * Atheros AR71XX/AR724X PCI support
- *
- * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
- * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#ifndef _ATH79_PCI_H
-#define _ATH79_PCI_H
-
-struct ath79_pci_irq {
- int bus;
- u8 slot;
- u8 pin;
- int irq;
-};
-
-#ifdef CONFIG_PCI
-void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map);
-void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
-int ath79_register_pci(void);
-#else
-static inline void
-ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {}
-static inline void
-ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
-static inline int ath79_register_pci(void) { return 0; }
-#endif
-
-#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 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/of_fdt.h>
+#include <linux/irqchip.h>
#include <asm/bootinfo.h>
#include <asm/idle.h>
@@ -31,8 +32,6 @@
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include "common.h"
-#include "dev-common.h"
-#include "machtypes.h"
#define ATH79_SYS_TYPE_LEN 64
@@ -235,25 +234,21 @@ void __init plat_mem_setup(void)
else if (fw_passed_dtb)
__dt_setup_arch((void *)KSEG0ADDR(fw_passed_dtb));
- if (mips_machtype != ATH79_MACH_GENERIC_OF) {
- ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
- AR71XX_RESET_SIZE);
- ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
- AR71XX_PLL_SIZE);
- ath79_detect_sys_type();
- ath79_ddr_ctrl_init();
+ ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
+ AR71XX_RESET_SIZE);
+ ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
+ AR71XX_PLL_SIZE);
+ ath79_detect_sys_type();
+ ath79_ddr_ctrl_init();
- detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
-
- /* OF machines should use the reset driver */
- _machine_restart = ath79_restart;
- }
+ detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
+ _machine_restart = ath79_restart;
_machine_halt = ath79_halt;
pm_power_off = ath79_halt;
}
-static void __init ath79_of_plat_time_init(void)
+void __init plat_time_init(void)
{
struct device_node *np;
struct clk *clk;
@@ -283,61 +278,12 @@ static void __init ath79_of_plat_time_init(void)
clk_put(clk);
}
-void __init plat_time_init(void)
-{
- unsigned long cpu_clk_rate;
- unsigned long ahb_clk_rate;
- unsigned long ddr_clk_rate;
- unsigned long ref_clk_rate;
-
- if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) {
- ath79_of_plat_time_init();
- return;
- }
-
- ath79_clocks_init();
-
- cpu_clk_rate = ath79_get_sys_clk_rate("cpu");
- ahb_clk_rate = ath79_get_sys_clk_rate("ahb");
- ddr_clk_rate = ath79_get_sys_clk_rate("ddr");
- ref_clk_rate = ath79_get_sys_clk_rate("ref");
-
- pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n",
- cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000,
- ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000,
- ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000,
- ref_clk_rate / 1000000, (ref_clk_rate / 1000) % 1000);
-
- mips_hpt_frequency = cpu_clk_rate / 2;
-}
-
-static int __init ath79_setup(void)
+void __init arch_init_irq(void)
{
- if (mips_machtype == ATH79_MACH_GENERIC_OF)
- return 0;
-
- ath79_gpio_init();
- ath79_register_uart();
- ath79_register_wdt();
-
- mips_machine_setup();
-
- return 0;
+ irqchip_init();
}
-arch_initcall(ath79_setup);
-
void __init device_tree_init(void)
{
unflatten_and_copy_device_tree();
}
-
-MIPS_MACHINE(ATH79_MACH_GENERIC,
- "Generic",
- "Generic AR71XX/AR724X/AR913X based board",
- NULL);
-
-MIPS_MACHINE(ATH79_MACH_GENERIC_OF,
- "DTB",
- "Generic AR71XX/AR724X/AR913X based board (DT)",
- 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 = {
static const struct gpio_keys_button
bcm47xx_buttons_buffalo_whr_g54s[] __initconst = {
BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
- BCM47XX_GPIO_KEY(4, KEY_RESTART),
+ BCM47XX_GPIO_KEY_H(4, KEY_RESTART),
BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
};
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 = {
static const struct gpio_led
bcm47xx_leds_buffalo_whr_g54s[] __initconst = {
- BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
- BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
- BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
- BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
- BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(1, "green", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(2, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(3, "green", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(6, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(7, "red", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
};
static 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 @@
ethernet@0 {
phy-handle = <&phy2>;
cavium,alt-phy-handle = <&phy100>;
+ rx-delay = <0>;
+ tx-delay = <0>;
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
};
ethernet@1 {
phy-handle = <&phy3>;
cavium,alt-phy-handle = <&phy101>;
+ rx-delay = <0>;
+ tx-delay = <0>;
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
};
ethernet@2 {
phy-handle = <&phy4>;
cavium,alt-phy-handle = <&phy102>;
+ rx-delay = <0>;
+ tx-delay = <0>;
};
ethernet@3 {
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 @@
interface@0 {
ethernet@0 {
phy-handle = <&phy7>;
+ rx-delay = <0>;
+ tx-delay = <0x10>;
};
ethernet@1 {
phy-handle = <&phy6>;
+ rx-delay = <0>;
+ tx-delay = <0x10>;
};
ethernet@2 {
phy-handle = <&phy5>;
+ rx-delay = <0>;
+ tx-delay = <0x10>;
};
};
};
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 @@
* network ports from the rest of the cvmx-helper files.
*/
+#include <linux/bug.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-bootinfo.h>
@@ -210,56 +211,18 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
{
cvmx_helper_link_info_t result;
+ WARN(!octeon_is_simulation(),
+ "Using deprecated link status - please update your DT");
+
/* Unless we fix it later, all links are defaulted to down */
result.u64 = 0;
- /*
- * This switch statement should handle all ports that either don't use
- * Marvell PHYS, or don't support in-band status.
- */
- switch (cvmx_sysinfo_get()->board_type) {
- case CVMX_BOARD_TYPE_SIM:
+ if (octeon_is_simulation()) {
/* The simulator gives you a simulated 1Gbps full duplex link */
result.s.link_up = 1;
result.s.full_duplex = 1;
result.s.speed = 1000;
return result;
- case CVMX_BOARD_TYPE_EBH3100:
- case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
- case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
- case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
- /* Port 1 on these boards is always Gigabit */
- if (ipd_port == 1) {
- result.s.link_up = 1;
- result.s.full_duplex = 1;
- result.s.speed = 1000;
- return result;
- }
- /* Fall through to the generic code below */
- break;
- case CVMX_BOARD_TYPE_CUST_NB5:
- /* Port 1 on these boards is always Gigabit */
- if (ipd_port == 1) {
- result.s.link_up = 1;
- result.s.full_duplex = 1;
- result.s.speed = 1000;
- return result;
- }
- break;
- case CVMX_BOARD_TYPE_BBGW_REF:
- /* Port 1 on these boards is always Gigabit */
- if (ipd_port == 2) {
- /* Port 2 is not hooked up */
- result.u64 = 0;
- return result;
- } else {
- /* Ports 0 and 1 connect to the switch */
- result.s.link_up = 1;
- result.s.full_duplex = 1;
- result.s.speed = 1000;
- return result;
- }
- break;
}
if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
@@ -358,45 +321,6 @@ int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
}
/**
- * Enable packet input/output from the hardware. This function is
- * called after by cvmx_helper_packet_hardware_enable() to
- * perform board specific initialization. For most boards
- * nothing is needed.
- *
- * @interface: Interface to enable
- *
- * Returns Zero on success, negative on failure
- */
-int __cvmx_helper_board_hardware_enable(int interface)
-{
- if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5) {
- if (interface == 0) {
- /* Different config for switch port */
- cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0);
- cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
- /*
- * Boards with gigabit WAN ports need a
- * different setting that is compatible with
- * 100 Mbit settings
- */
- cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface),
- 0xc);
- cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface),
- 0xc);
- }
- } else if (cvmx_sysinfo_get()->board_type ==
- CVMX_BOARD_TYPE_UBNT_E100) {
- cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0);
- cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10);
- cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
- cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0x10);
- cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(2, interface), 0);
- cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(2, interface), 0x10);
- }
- return 0;
-}
-
-/**
* Get the clock type used for the USB block based on board type.
* Used by the USB code for auto configuration of clock type.
*
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 @@
* Helper functions for common, but complicated tasks.
*
*/
+#include <linux/bug.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-config.h>
@@ -43,7 +44,6 @@
#include <asm/octeon/cvmx-helper-board.h>
#include <asm/octeon/cvmx-pip-defs.h>
-#include <asm/octeon/cvmx-smix-defs.h>
#include <asm/octeon/cvmx-asxx-defs.h>
/* Port count per interface */
@@ -317,22 +317,6 @@ cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
return CVMX_HELPER_INTERFACE_MODE_DISABLED;
}
- if (interface == 0
- && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
- && cvmx_sysinfo_get()->board_rev_major == 1) {
- /*
- * Lie about interface type of CN3005 board. This
- * board has a switch on port 1 like the other
- * evaluation boards, but it is connected over RGMII
- * instead of GMII. Report GMII mode so that the
- * speed is forced to 1 Gbit full duplex. Other than
- * some initial configuration (which does not use the
- * output of this function) there is no difference in
- * setup between GMII and RGMII modes.
- */
- return CVMX_HELPER_INTERFACE_MODE_GMII;
- }
-
/* Interface 1 is always disabled on CN31XX and CN30XX */
if ((interface == 1)
&& (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
@@ -778,7 +762,6 @@ static int __cvmx_helper_packet_hardware_enable(int interface)
result = __cvmx_helper_loop_enable(interface);
break;
}
- result |= __cvmx_helper_board_hardware_enable(interface);
return result;
}
@@ -1026,7 +1009,6 @@ int cvmx_helper_initialize_packet_io_global(void)
int result = 0;
int interface;
union cvmx_l2c_cfg l2c_cfg;
- union cvmx_smix_en smix_en;
const int num_interfaces = cvmx_helper_get_number_of_interfaces();
/*
@@ -1046,24 +1028,6 @@ int cvmx_helper_initialize_packet_io_global(void)
l2c_cfg.s.rfb_arb_mode = 0;
cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
- /* Make sure SMI/MDIO is enabled so we can query PHYs */
- smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
- if (!smix_en.s.en) {
- smix_en.s.en = 1;
- cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
- }
-
- /* Newer chips actually have two SMI/MDIO interfaces */
- if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
- !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
- !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
- smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
- if (!smix_en.s.en) {
- smix_en.s.en = 1;
- cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
- }
- }
-
cvmx_pko_initialize_global();
for (interface = 0; interface < num_interfaces; interface++) {
result |= cvmx_helper_interface_probe(interface);
@@ -1136,6 +1100,7 @@ cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
if (index == 0)
result = __cvmx_helper_rgmii_link_get(ipd_port);
else {
+ WARN(1, "Using deprecated link status - please update your DT");
result.s.full_duplex = 1;
result.s.link_up = 1;
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)
DEFINE_SIMPLE_ATTRIBUTE(reset_statistics_ops, NULL, reset_statistics, "%llu\n");
-static int init_debufs(void)
+static void init_debugfs(void)
{
- struct dentry *show_dentry;
dir = debugfs_create_dir("oct_ilm", 0);
- if (!dir) {
- pr_err("oct_ilm: failed to create debugfs entry oct_ilm\n");
- return -1;
- }
-
- show_dentry = debugfs_create_file("statistics", 0222, dir, NULL,
- &oct_ilm_ops);
- if (!show_dentry) {
- pr_err("oct_ilm: failed to create debugfs entry oct_ilm/statistics\n");
- return -1;
- }
-
- show_dentry = debugfs_create_file("reset", 0222, dir, NULL,
- &reset_statistics_ops);
- if (!show_dentry) {
- pr_err("oct_ilm: failed to create debugfs entry oct_ilm/reset\n");
- return -1;
- }
-
- return 0;
-
+ debugfs_create_file("statistics", 0222, dir, NULL, &oct_ilm_ops);
+ debugfs_create_file("reset", 0222, dir, NULL, &reset_statistics_ops);
}
static void init_latency_info(struct latency_info *li, int startup)
@@ -169,11 +149,7 @@ static __init int oct_ilm_module_init(void)
int rc;
int irq = OCTEON_IRQ_TIMER0 + TIMER_NUM;
- rc = init_debufs();
- if (rc) {
- WARN(1, "Could not create debugfs entries");
- return rc;
- }
+ init_debugfs();
rc = request_irq(irq, cvm_oct_ciu_timer_interrupt, IRQF_NO_THREAD,
"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)
!OCTEON_IS_MODEL(OCTEON_CN56XX);
}
+static bool __init octeon_has_fixed_link(int ipd_port)
+{
+ switch (cvmx_sysinfo_get()->board_type) {
+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
+ case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
+ case CVMX_BOARD_TYPE_CUST_NB5:
+ case CVMX_BOARD_TYPE_EBH3100:
+ /* Port 1 on these boards is always gigabit. */
+ return ipd_port == 1;
+ case CVMX_BOARD_TYPE_BBGW_REF:
+ /* Ports 0 and 1 connect to the switch. */
+ return ipd_port == 0 || ipd_port == 1;
+ }
+ return false;
+}
+
static void __init octeon_fdt_set_phy(int eth, int phy_addr)
{
const __be32 *phy_handle;
@@ -586,12 +603,52 @@ static void __init octeon_fdt_rm_ethernet(int node)
fdt_nop_node(initial_boot_params, node);
}
+static void __init _octeon_rx_tx_delay(int eth, int rx_delay, int tx_delay)
+{
+ fdt_setprop_inplace_cell(initial_boot_params, eth, "rx-delay",
+ rx_delay);
+ fdt_setprop_inplace_cell(initial_boot_params, eth, "tx-delay",
+ tx_delay);
+}
+
+static void __init octeon_rx_tx_delay(int eth, int iface, int port)
+{
+ switch (cvmx_sysinfo_get()->board_type) {
+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+ if (iface == 0) {
+ if (port == 0) {
+ /*
+ * Boards with gigabit WAN ports need a
+ * different setting that is compatible with
+ * 100 Mbit settings
+ */
+ _octeon_rx_tx_delay(eth, 0xc, 0x0c);
+ return;
+ } else if (port == 1) {
+ /* Different config for switch port. */
+ _octeon_rx_tx_delay(eth, 0x0, 0x0);
+ return;
+ }
+ }
+ break;
+ case CVMX_BOARD_TYPE_UBNT_E100:
+ if (iface == 0 && port <= 2) {
+ _octeon_rx_tx_delay(eth, 0x0, 0x10);
+ return;
+ }
+ break;
+ }
+ fdt_nop_property(initial_boot_params, eth, "rx-delay");
+ fdt_nop_property(initial_boot_params, eth, "tx-delay");
+}
+
static void __init octeon_fdt_pip_port(int iface, int i, int p, int max)
{
char name_buffer[20];
int eth;
int phy_addr;
int ipd_port;
+ int fixed_link;
snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p);
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)
phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
octeon_fdt_set_phy(eth, phy_addr);
+
+ fixed_link = fdt_subnode_offset(initial_boot_params, eth, "fixed-link");
+ if (fixed_link < 0)
+ WARN_ON(octeon_has_fixed_link(ipd_port));
+ else if (!octeon_has_fixed_link(ipd_port))
+ fdt_nop_node(initial_boot_params, fixed_link);
+ octeon_rx_tx_delay(eth, i, p);
}
static 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
# CONFIG_COMPAT_BRK is not set
CONFIG_LANTIQ=y
CONFIG_PCI_LANTIQ=y
-CONFIG_XRX200_PHY_FW=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_MIPS_VPE_LOADER=y
CONFIG_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
generated-y += syscall_table_64_n32.h
generated-y += syscall_table_64_n64.h
generated-y += syscall_table_64_o32.h
-generic-(CONFIG_GENERIC_CSUM) += checksum.h
generic-y += current.h
generic-y += device.h
generic-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 @@
*/
#define STYPE_SYNC_MB 0x10
+/*
+ * stype 0x14 - A completion barrier specific to global invalidations
+ *
+ * When a sync instruction of this type completes any preceding GINVI or GINVT
+ * operation has been globalized & completed on all coherent CPUs. Anything
+ * that the GINV* instruction should invalidate will have been invalidated on
+ * all coherent CPUs when this instruction completes. It is implementation
+ * specific whether the GINV* instructions themselves will ensure completion,
+ * or this sync type will.
+ *
+ * In systems implementing global invalidates (ie. with Config5.GI == 2 or 3)
+ * this sync type also requires that previous SYNCI operations have completed.
+ */
+#define STYPE_GINV 0x14
#ifdef CONFIG_CPU_HAS_SYNC
#define __sync() \
@@ -258,6 +272,11 @@
#define loongson_llsc_mb() do { } while (0)
#endif
+static inline void sync_ginv(void)
+{
+ asm volatile("sync\t%0" :: "i"(STYPE_GINV));
+}
+
#include <asm-generic/barrier.h>
#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 @@
*
* MIPS specific flush operations:
*
- * - flush_cache_sigtramp() flush signal trampoline
* - flush_icache_all() flush the entire instruction cache
* - flush_data_cache_page() flushes a page from the data cache
* - __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,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len);
-extern void (*flush_cache_sigtramp)(unsigned long addr);
extern void (*flush_icache_all)(void);
extern void (*local_flush_data_cache_page)(void * addr);
extern 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 @@
*/
extern unsigned long __cmpxchg_called_with_bad_pointer(void)
__compiletime_error("Bad argument size for cmpxchg");
+extern unsigned long __cmpxchg64_unsupported(void)
+ __compiletime_error("cmpxchg64 not available; cpu_has_64bits may be false");
extern unsigned long __xchg_called_with_bad_pointer(void)
__compiletime_error("Bad argument size for xchg");
@@ -204,12 +206,102 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
cmpxchg((ptr), (o), (n)); \
})
#else
-#include <asm-generic/cmpxchg-local.h>
-#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-#ifndef CONFIG_SMP
-#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
-#endif
-#endif
+
+# include <asm-generic/cmpxchg-local.h>
+# define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+# ifdef CONFIG_SMP
+
+static inline unsigned long __cmpxchg64(volatile void *ptr,
+ unsigned long long old,
+ unsigned long long new)
+{
+ unsigned long long tmp, ret;
+ unsigned long flags;
+
+ /*
+ * The assembly below has to combine 32 bit values into a 64 bit
+ * register, and split 64 bit values from one register into two. If we
+ * were to take an interrupt in the middle of this we'd only save the
+ * least significant 32 bits of each register & probably clobber the
+ * most significant 32 bits of the 64 bit values we're using. In order
+ * to avoid this we must disable interrupts.
+ */
+ local_irq_save(flags);
+
+ asm volatile(
+ " .set push \n"
+ " .set " MIPS_ISA_ARCH_LEVEL " \n"
+ /* Load 64 bits from ptr */
+ "1: lld %L0, %3 # __cmpxchg64 \n"
+ /*
+ * Split the 64 bit value we loaded into the 2 registers that hold the
+ * ret variable.
+ */
+ " dsra %M0, %L0, 32 \n"
+ " sll %L0, %L0, 0 \n"
+ /*
+ * Compare ret against old, breaking out of the loop if they don't
+ * match.
+ */
+ " bne %M0, %M4, 2f \n"
+ " bne %L0, %L4, 2f \n"
+ /*
+ * Combine the 32 bit halves from the 2 registers that hold the new
+ * variable into a single 64 bit register.
+ */
+# if MIPS_ISA_REV >= 2
+ " move %L1, %L5 \n"
+ " dins %L1, %M5, 32, 32 \n"
+# else
+ " dsll %L1, %L5, 32 \n"
+ " dsrl %L1, %L1, 32 \n"
+ " .set noat \n"
+ " dsll $at, %M5, 32 \n"
+ " or %L1, %L1, $at \n"
+ " .set at \n"
+# endif
+ /* Attempt to store new at ptr */
+ " scd %L1, %2 \n"
+ /* If we failed, loop! */
+ "\t" __scbeqz " %L1, 1b \n"
+ " .set pop \n"
+ "2: \n"
+ : "=&r"(ret),
+ "=&r"(tmp),
+ "=" GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr)
+ : GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr),
+ "r" (old),
+ "r" (new)
+ : "memory");
+
+ local_irq_restore(flags);
+ return ret;
+}
+
+# define cmpxchg64(ptr, o, n) ({ \
+ unsigned long long __old = (__typeof__(*(ptr)))(o); \
+ unsigned long long __new = (__typeof__(*(ptr)))(n); \
+ __typeof__(*(ptr)) __res; \
+ \
+ /* \
+ * We can only use cmpxchg64 if we know that the CPU supports \
+ * 64-bits, ie. lld & scd. Our call to __cmpxchg64_unsupported \
+ * will cause a build error unless cpu_has_64bits is a \
+ * compile-time constant 1. \
+ */ \
+ if (cpu_has_64bits && kernel_uses_llsc) \
+ __res = __cmpxchg64((ptr), __old, __new); \
+ else \
+ __res = __cmpxchg64_unsupported(); \
+ \
+ __res; \
+})
+
+# else /* !CONFIG_SMP */
+# define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
+# endif /* !CONFIG_SMP */
+#endif /* !CONFIG_64BIT */
#undef __scbeqz
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 @@
#endif /* CONFIG_MIPS_MT_SMP */
/*
+ * We only enable MMID support for configurations which natively support 64 bit
+ * atomics because getting good performance from the allocator relies upon
+ * efficient atomic64_*() functions.
+ */
+#ifndef cpu_has_mmid
+# ifdef CONFIG_GENERIC_ATOMIC64
+# define cpu_has_mmid 0
+# else
+# define cpu_has_mmid __isa_ge_and_opt(6, MIPS_CPU_MMID)
+# endif
+#endif
+
+/*
* Guest capabilities
*/
#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 {
MBIT_ULL(55) /* CPU shares FTLB entries with another */
#define MIPS_CPU_MT_PER_TC_PERF_COUNTERS \
MBIT_ULL(56) /* CPU has perf counters implemented per TC (MIPSMT ASE) */
+#define MIPS_CPU_MMID MBIT_ULL(57) /* CPU supports MemoryMapIDs */
/*
* 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 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __MIPS_ASM_GINVT_H__
+#define __MIPS_ASM_GINVT_H__
+
+#include <asm/mipsregs.h>
+
+enum ginvt_type {
+ GINVT_FULL,
+ GINVT_VA,
+ GINVT_MMID,
+};
+
+#ifdef TOOLCHAIN_SUPPORTS_GINV
+# define _ASM_SET_GINV ".set ginv\n"
+#else
+_ASM_MACRO_1R1I(ginvt, rs, type,
+ _ASM_INSN_IF_MIPS(0x7c0000bd | (__rs << 21) | (\\type << 8))
+ _ASM_INSN32_IF_MM(0x0000717c | (__rs << 16) | (\\type << 9)));
+# define _ASM_SET_GINV
+#endif
+
+static inline void ginvt(unsigned long addr, enum ginvt_type type)
+{
+ asm volatile(
+ ".set push\n"
+ _ASM_SET_GINV
+ " ginvt %0, %1\n"
+ ".set pop"
+ : /* no outputs */
+ : "r"(addr), "i"(type)
+ : "memory");
+}
+
+static inline void ginvt_full(void)
+{
+ ginvt(0, GINVT_FULL);
+}
+
+static inline void ginvt_va(unsigned long addr)
+{
+ addr &= PAGE_MASK << 1;
+ ginvt(addr, GINVT_VA);
+}
+
+static inline void ginvt_mmid(void)
+{
+ ginvt(0, GINVT_MMID);
+}
+
+static inline void ginvt_va_mmid(unsigned long addr)
+{
+ addr &= PAGE_MASK << 1;
+ ginvt(addr, GINVT_VA | GINVT_MMID);
+}
+
+#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)
" .set push \n"
" .set reorder \n"
" .set noat \n"
-#if defined(CONFIG_CPU_LOONGSON3)
+#if defined(CONFIG_CPU_LOONGSON3) || defined (CONFIG_CPU_LOONGSON1)
" mfc0 %[flags], $12 \n"
" di \n"
#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)
void ath79_device_reset_set(u32 mask);
void ath79_device_reset_clear(u32 mask);
-void ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3);
-void ath79_misc_irq_init(void __iomem *regs, int irq,
- int irq_base, bool is_ar71xx);
-
#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 @@
#ifndef __ASM_MACH_IP27_IRQ_H
#define __ASM_MACH_IP27_IRQ_H
-/*
- * A hardwired interrupt number is completely stupid for this system - a
- * large configuration might have thousands if not tenthousands of
- * interrupts.
- */
#define NR_IRQS 256
#include_next <irq.h>
+#define IP27_HUB_PEND0_IRQ (MIPS_CPU_IRQ_BASE + 2)
+#define IP27_HUB_PEND1_IRQ (MIPS_CPU_IRQ_BASE + 3)
+#define IP27_RT_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 4)
+
+#define IP27_HUB_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
+#define IP27_HUB_IRQ_COUNT 128
+
#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 @@
#define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr))
-#define LEVELS_PER_SLICE 128
-
-struct slice_data {
- unsigned long irq_enable_mask[2];
- int level_to_irq[LEVELS_PER_SLICE];
-};
-
struct hub_data {
kern_vars_t kern_vars;
DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
cpumask_t h_cpus;
unsigned long slice_map;
- unsigned long irq_alloc_mask[2];
- struct slice_data slice[2];
};
struct 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 @@
extern struct platform_device ls1x_uart_pdev;
extern struct platform_device ls1x_cpufreq_pdev;
-extern struct platform_device ls1x_dma_pdev;
extern struct platform_device ls1x_eth0_pdev;
extern struct platform_device ls1x_eth1_pdev;
extern struct platform_device ls1x_ehci_pdev;
extern struct platform_device ls1x_gpio0_pdev;
extern struct platform_device ls1x_gpio1_pdev;
-extern struct platform_device ls1x_nand_pdev;
extern struct platform_device ls1x_rtc_pdev;
extern struct platform_device ls1x_wdt_pdev;
void __init ls1x_clk_init(void);
-void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata);
-void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata);
void __init ls1x_rtc_set_extclk(struct platform_device *pdev);
void __init ls1x_serial_set_uartclk(struct platform_device *pdev);
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 @@
#define MIPS_CONF5_FRE (_ULCAST_(1) << 8)
#define MIPS_CONF5_UFE (_ULCAST_(1) << 9)
#define MIPS_CONF5_CA2 (_ULCAST_(1) << 14)
+#define MIPS_CONF5_MI (_ULCAST_(1) << 17)
#define MIPS_CONF5_CRCP (_ULCAST_(1) << 18)
#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27)
#define MIPS_CONF5_EVA (_ULCAST_(1) << 28)
@@ -1247,6 +1248,13 @@ __asm__(".macro parse_r var r\n\t"
ENC \
".endm")
+/* Instructions with 1 register operand & 1 immediate operand */
+#define _ASM_MACRO_1R1I(OP, R1, I2, ENC) \
+ __asm__(".macro " #OP " " #R1 ", " #I2 "\n\t" \
+ "parse_r __" #R1 ", \\" #R1 "\n\t" \
+ ENC \
+ ".endm")
+
/* Instructions with 2 register operands */
#define _ASM_MACRO_2R(OP, R1, R2, ENC) \
__asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \
@@ -1603,6 +1611,9 @@ do { \
#define read_c0_xcontextconfig() __read_ulong_c0_register($4, 3)
#define write_c0_xcontextconfig(val) __write_ulong_c0_register($4, 3, val)
+#define read_c0_memorymapid() __read_32bit_c0_register($4, 5)
+#define write_c0_memorymapid(val) __write_32bit_c0_register($4, 5, val)
+
#define read_c0_pagemask() __read_32bit_c0_register($5, 0)
#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
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 @@
#include <linux/wait.h>
typedef struct {
- u64 asid[NR_CPUS];
+ union {
+ u64 asid[NR_CPUS];
+ atomic64_t mmid;
+ };
+
void *vdso;
/* 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 @@
#include <linux/smp.h>
#include <linux/slab.h>
+#include <asm/barrier.h>
#include <asm/cacheflush.h>
#include <asm/dsemul.h>
+#include <asm/ginvt.h>
#include <asm/hazards.h>
#include <asm/tlbflush.h>
#include <asm-generic/mm_hooks.h>
@@ -73,6 +75,19 @@ extern unsigned long pgd_current[];
#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
/*
+ * The ginvt instruction will invalidate wired entries when its type field
+ * targets anything other than the entire TLB. That means that if we were to
+ * allow the kernel to create wired entries with the MMID of current->active_mm
+ * then those wired entries could be invalidated when we later use ginvt to
+ * invalidate TLB entries with that MMID.
+ *
+ * In order to prevent ginvt from trashing wired entries, we reserve one MMID
+ * for use by the kernel when creating wired entries. This MMID will never be
+ * assigned to a struct mm, and we'll never target it with a ginvt instruction.
+ */
+#define MMID_KERNEL_WIRED 0
+
+/*
* All unused by hardware upper bits will be considered
* as a software asid extension.
*/
@@ -88,7 +103,23 @@ static inline u64 asid_first_version(unsigned int cpu)
return ~asid_version_mask(cpu) + 1;
}
-#define cpu_context(cpu, mm) ((mm)->context.asid[cpu])
+static inline u64 cpu_context(unsigned int cpu, const struct mm_struct *mm)
+{
+ if (cpu_has_mmid)
+ return atomic64_read(&mm->context.mmid);
+
+ return mm->context.asid[cpu];
+}
+
+static inline void set_cpu_context(unsigned int cpu,
+ struct mm_struct *mm, u64 ctx)
+{
+ if (cpu_has_mmid)
+ atomic64_set(&mm->context.mmid, ctx);
+ else
+ mm->context.asid[cpu] = ctx;
+}
+
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
#define cpu_asid(cpu, mm) \
(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)
{
}
-
-/* Normal, classic MIPS get_new_mmu_context */
-static inline void
-get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
-{
- u64 asid = asid_cache(cpu);
-
- if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) {
- if (cpu_has_vtag_icache)
- flush_icache_all();
- local_flush_tlb_all(); /* start new asid cycle */
- }
-
- cpu_context(cpu, mm) = asid_cache(cpu) = asid;
-}
+extern void get_new_mmu_context(struct mm_struct *mm);
+extern void check_mmu_context(struct mm_struct *mm);
+extern void check_switch_mmu_context(struct mm_struct *mm);
/*
* 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)
{
int i;
- for_each_possible_cpu(i)
- cpu_context(i, mm) = 0;
+ if (cpu_has_mmid) {
+ set_cpu_context(0, mm, 0);
+ } else {
+ for_each_possible_cpu(i)
+ set_cpu_context(i, mm, 0);
+ }
mm->context.bd_emupage_allocmap = NULL;
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,
local_irq_save(flags);
htw_stop();
- /* Check if our ASID is of an older version and thus invalid */
- if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & asid_version_mask(cpu))
- get_new_mmu_context(next, cpu);
- write_c0_entryhi(cpu_asid(cpu, next));
- TLBMISS_HANDLER_SETUP_PGD(next->pgd);
+ check_switch_mmu_context(next);
/*
* Mark current->active_mm as not "active" anymore.
@@ -166,55 +185,55 @@ static inline void destroy_context(struct mm_struct *mm)
dsemul_mm_cleanup(mm);
}
+#define activate_mm(prev, next) switch_mm(prev, next, current)
#define deactivate_mm(tsk, mm) do { } while (0)
-/*
- * After we have set current->mm to a new value, this activates
- * the context for the new mm so we see the new mappings.
- */
-static inline void
-activate_mm(struct mm_struct *prev, struct mm_struct *next)
-{
- unsigned long flags;
- unsigned int cpu = smp_processor_id();
-
- local_irq_save(flags);
-
- htw_stop();
- /* Unconditionally get a new ASID. */
- get_new_mmu_context(next, cpu);
-
- write_c0_entryhi(cpu_asid(cpu, next));
- TLBMISS_HANDLER_SETUP_PGD(next->pgd);
-
- /* mark mmu ownership change */
- cpumask_clear_cpu(cpu, mm_cpumask(prev));
- cpumask_set_cpu(cpu, mm_cpumask(next));
- htw_start();
-
- local_irq_restore(flags);
-}
-
-/*
- * If mm is currently active_mm, we can't really drop it. Instead,
- * we will get a new one for it.
- */
static inline void
-drop_mmu_context(struct mm_struct *mm, unsigned cpu)
+drop_mmu_context(struct mm_struct *mm)
{
unsigned long flags;
+ unsigned int cpu;
+ u32 old_mmid;
+ u64 ctx;
local_irq_save(flags);
- htw_stop();
- if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
- get_new_mmu_context(mm, cpu);
+ cpu = smp_processor_id();
+ ctx = cpu_context(cpu, mm);
+
+ if (!ctx) {
+ /* no-op */
+ } else if (cpu_has_mmid) {
+ /*
+ * Globally invalidating TLB entries associated with the MMID
+ * is pretty cheap using the GINVT instruction, so we'll do
+ * that rather than incur the overhead of allocating a new
+ * MMID. The latter would be especially difficult since MMIDs
+ * are global & other CPUs may be actively using ctx.
+ */
+ htw_stop();
+ old_mmid = read_c0_memorymapid();
+ write_c0_memorymapid(ctx & cpu_asid_mask(&cpu_data[cpu]));
+ mtc0_tlbw_hazard();
+ ginvt_mmid();
+ sync_ginv();
+ write_c0_memorymapid(old_mmid);
+ instruction_hazard();
+ htw_start();
+ } else if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
+ /*
+ * mm is currently active, so we can't really drop it.
+ * Instead we bump the ASID.
+ */
+ htw_stop();
+ get_new_mmu_context(mm);
write_c0_entryhi(cpu_asid(cpu, mm));
+ htw_start();
} else {
/* will get a new context next time */
- cpu_context(cpu, mm) = 0;
+ set_cpu_context(cpu, mm, 0);
}
- htw_start();
+
local_irq_restore(flags);
}
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);
extern int __cvmx_helper_board_interface_probe(int interface,
int supported_ports);
-/**
- * Enable packet input/output from the hardware. This function is
- * called after by cvmx_helper_packet_hardware_enable() to
- * perform board specific initialization. For most boards
- * nothing is needed.
- *
- * @interface: Interface to enable
- *
- * Returns Zero on success, negative on failure
- */
-extern int __cvmx_helper_board_hardware_enable(int interface);
-
enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void);
#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 @@
-/***********************license start***************
- * Author: Cavium Networks
- *
- * Contact: support@caviumnetworks.com
- * This file is part of the OCTEON SDK
- *
- * Copyright (c) 2003-2012 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- *
- * This file is distributed in the hope that it will be useful, but
- * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
- * NONINFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- * or visit http://www.gnu.org/licenses/.
- *
- * This file may also be available under a different license from Cavium.
- * Contact Cavium Networks for more information
- ***********************license end**************************************/
-
-#ifndef __CVMX_SMIX_DEFS_H__
-#define __CVMX_SMIX_DEFS_H__
-
-static inline uint64_t CVMX_SMIX_CLK(unsigned long offset)
-{
- switch (cvmx_get_octeon_family()) {
- case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
- case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
- case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000003818ull) + (offset) * 128;
- }
- return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
-}
-
-static inline uint64_t CVMX_SMIX_CMD(unsigned long offset)
-{
- switch (cvmx_get_octeon_family()) {
- case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
- case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
- case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000003800ull) + (offset) * 128;
- }
- return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
-}
-
-static inline uint64_t CVMX_SMIX_EN(unsigned long offset)
-{
- switch (cvmx_get_octeon_family()) {
- case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
- case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
- case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000003820ull) + (offset) * 128;
- }
- return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
-}
-
-static inline uint64_t CVMX_SMIX_RD_DAT(unsigned long offset)
-{
- switch (cvmx_get_octeon_family()) {
- case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
- case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
- case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000003810ull) + (offset) * 128;
- }
- return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
-}
-
-static inline uint64_t CVMX_SMIX_WR_DAT(unsigned long offset)
-{
- switch (cvmx_get_octeon_family()) {
- case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
- case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
- case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
- case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
- return CVMX_ADD_IO_SEG(0x0001180000003808ull) + (offset) * 128;
- }
- return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
-}
-
-union cvmx_smix_clk {
- uint64_t u64;
- struct cvmx_smix_clk_s {
-#ifdef __BIG_ENDIAN_BITFIELD
- uint64_t reserved_25_63:39;
- uint64_t mode:1;
- uint64_t reserved_21_23:3;
- uint64_t sample_hi:5;
- uint64_t sample_mode:1;
- uint64_t reserved_14_14:1;
- uint64_t clk_idle:1;
- uint64_t preamble:1;
- uint64_t sample:4;
- uint64_t phase:8;
-#else
- uint64_t phase:8;
- uint64_t sample:4;
- uint64_t preamble:1;
- uint64_t clk_idle:1;
- uint64_t reserved_14_14:1;
- uint64_t sample_mode:1;
- uint64_t sample_hi:5;
- uint64_t reserved_21_23:3;
- uint64_t mode:1;
- uint64_t reserved_25_63:39;
-#endif
- } s;
- struct cvmx_smix_clk_cn30xx {
-#ifdef __BIG_ENDIAN_BITFIELD
- uint64_t reserved_21_63:43;
- uint64_t sample_hi:5;
- uint64_t sample_mode:1;
- uint64_t reserved_14_14:1;
- uint64_t clk_idle:1;
- uint64_t preamble:1;
- uint64_t sample:4;
- uint64_t phase:8;
-#else
- uint64_t phase:8;
- uint64_t sample:4;
- uint64_t preamble:1;
- uint64_t clk_idle:1;
- uint64_t reserved_14_14:1;
- uint64_t sample_mode:1;
- uint64_t sample_hi:5;
- uint64_t reserved_21_63:43;
-#endif
- } cn30xx;
-};
-
-union cvmx_smix_cmd {
- uint64_t u64;
- struct cvmx_smix_cmd_s {
-#ifdef __BIG_ENDIAN_BITFIELD
- uint64_t reserved_18_63:46;
- uint64_t phy_op:2;
- uint64_t reserved_13_15:3;
- uint64_t phy_adr:5;
- uint64_t reserved_5_7:3;
- uint64_t reg_adr:5;
-#else
- uint64_t reg_adr:5;
- uint64_t reserved_5_7:3;
- uint64_t phy_adr:5;
- uint64_t reserved_13_15:3;
- uint64_t phy_op:2;
- uint64_t reserved_18_63:46;
-#endif
- } s;
- struct cvmx_smix_cmd_cn30xx {
-#ifdef __BIG_ENDIAN_BITFIELD
- uint64_t reserved_17_63:47;
- uint64_t phy_op:1;
- uint64_t reserved_13_15:3;
- uint64_t phy_adr:5;
- uint64_t reserved_5_7:3;
- uint64_t reg_adr:5;
-#else
- uint64_t reg_adr:5;
- uint64_t reserved_5_7:3;
- uint64_t phy_adr:5;
- uint64_t reserved_13_15:3;
- uint64_t phy_op:1;
- uint64_t reserved_17_63:47;
-#endif
- } cn30xx;
-};
-
-union cvmx_smix_en {
- uint64_t u64;
- struct cvmx_smix_en_s {
-#ifdef __BIG_ENDIAN_BITFIELD
- uint64_t reserved_1_63:63;
- uint64_t en:1;
-#else
- uint64_t en:1;
- uint64_t reserved_1_63:63;
-#endif
- } s;
-};
-
-union cvmx_smix_rd_dat {
- uint64_t u64;
- struct cvmx_smix_rd_dat_s {
-#ifdef __BIG_ENDIAN_BITFIELD
- uint64_t reserved_18_63:46;
- uint64_t pending:1;
- uint64_t val:1;
- uint64_t dat:16;
-#else
- uint64_t dat:16;
- uint64_t val:1;
- uint64_t pending:1;
- uint64_t reserved_18_63:46;
-#endif
- } s;
-};
-
-union cvmx_smix_wr_dat {
- uint64_t u64;
- struct cvmx_smix_wr_dat_s {
-#ifdef __BIG_ENDIAN_BITFIELD
- uint64_t reserved_18_63:46;
- uint64_t pending:1;
- uint64_t val:1;
- uint64_t dat:16;
-#else
- uint64_t dat:16;
- uint64_t val:1;
- uint64_t pending:1;
- uint64_t reserved_18_63:46;
-#endif
- } s;
-};
-
-#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 @@
#ifndef __ASSEMBLY__
-/*
- * All accesses to bridge hardware registers must be done
- * using 32-bit loads and stores.
- */
-typedef u32 bridgereg_t;
+#define ATE_V 0x01
+#define ATE_CO 0x02
+#define ATE_PREC 0x04
+#define ATE_PREF 0x08
+#define ATE_BAR 0x10
+
+#define ATE_PFNSHIFT 12
+#define ATE_TIDSHIFT 8
+#define ATE_RMFSHIFT 48
-typedef u64 bridge_ate_t;
+#define mkate(xaddr, xid, attr) (((xaddr) & 0x0000fffffffff000ULL) | \
+ ((xid)<<ATE_TIDSHIFT) | \
+ (attr))
-/* pointers to bridge ATEs
- * are always "pointer to volatile"
- */
-typedef volatile bridge_ate_t *bridge_ate_p;
+#define BRIDGE_INTERNAL_ATES 128
/*
* It is generally preferred that hardware registers on the bridge
@@ -65,7 +68,7 @@ typedef volatile bridge_ate_t *bridge_ate_p;
* Generated from Bridge spec dated 04oct95
*/
-typedef volatile struct bridge_s {
+struct bridge_regs {
/* Local Registers 0x000000-0x00FFFF */
/* standard widget configuration 0x000000-0x000057 */
@@ -86,105 +89,105 @@ typedef volatile struct bridge_s {
#define b_wid_tflush b_widget.w_tflush
/* bridge-specific widget configuration 0x000058-0x00007F */
- bridgereg_t _pad_000058;
- bridgereg_t b_wid_aux_err; /* 0x00005C */
- bridgereg_t _pad_000060;
- bridgereg_t b_wid_resp_upper; /* 0x000064 */
- bridgereg_t _pad_000068;
- bridgereg_t b_wid_resp_lower; /* 0x00006C */
- bridgereg_t _pad_000070;
- bridgereg_t b_wid_tst_pin_ctrl; /* 0x000074 */
- bridgereg_t _pad_000078[2];
+ u32 _pad_000058;
+ u32 b_wid_aux_err; /* 0x00005C */
+ u32 _pad_000060;
+ u32 b_wid_resp_upper; /* 0x000064 */
+ u32 _pad_000068;
+ u32 b_wid_resp_lower; /* 0x00006C */
+ u32 _pad_000070;
+ u32 b_wid_tst_pin_ctrl; /* 0x000074 */
+ u32 _pad_000078[2];
/* PMU & Map 0x000080-0x00008F */
- bridgereg_t _pad_000080;
- bridgereg_t b_dir_map; /* 0x000084 */
- bridgereg_t _pad_000088[2];
+ u32 _pad_000080;
+ u32 b_dir_map; /* 0x000084 */
+ u32 _pad_000088[2];
/* SSRAM 0x000090-0x00009F */
- bridgereg_t _pad_000090;
- bridgereg_t b_ram_perr; /* 0x000094 */
- bridgereg_t _pad_000098[2];
+ u32 _pad_000090;
+ u32 b_ram_perr; /* 0x000094 */
+ u32 _pad_000098[2];
/* Arbitration 0x0000A0-0x0000AF */
- bridgereg_t _pad_0000A0;
- bridgereg_t b_arb; /* 0x0000A4 */
- bridgereg_t _pad_0000A8[2];
+ u32 _pad_0000A0;
+ u32 b_arb; /* 0x0000A4 */
+ u32 _pad_0000A8[2];
/* Number In A Can 0x0000B0-0x0000BF */
- bridgereg_t _pad_0000B0;
- bridgereg_t b_nic; /* 0x0000B4 */
- bridgereg_t _pad_0000B8[2];
+ u32 _pad_0000B0;
+ u32 b_nic; /* 0x0000B4 */
+ u32 _pad_0000B8[2];
/* PCI/GIO 0x0000C0-0x0000FF */
- bridgereg_t _pad_0000C0;
- bridgereg_t b_bus_timeout; /* 0x0000C4 */
+ u32 _pad_0000C0;
+ u32 b_bus_timeout; /* 0x0000C4 */
#define b_pci_bus_timeout b_bus_timeout
- bridgereg_t _pad_0000C8;
- bridgereg_t b_pci_cfg; /* 0x0000CC */
- bridgereg_t _pad_0000D0;
- bridgereg_t b_pci_err_upper; /* 0x0000D4 */
- bridgereg_t _pad_0000D8;
- bridgereg_t b_pci_err_lower; /* 0x0000DC */
- bridgereg_t _pad_0000E0[8];
+ u32 _pad_0000C8;
+ u32 b_pci_cfg; /* 0x0000CC */
+ u32 _pad_0000D0;
+ u32 b_pci_err_upper; /* 0x0000D4 */
+ u32 _pad_0000D8;
+ u32 b_pci_err_lower; /* 0x0000DC */
+ u32 _pad_0000E0[8];
#define b_gio_err_lower b_pci_err_lower
#define b_gio_err_upper b_pci_err_upper
/* Interrupt 0x000100-0x0001FF */
- bridgereg_t _pad_000100;
- bridgereg_t b_int_status; /* 0x000104 */
- bridgereg_t _pad_000108;
- bridgereg_t b_int_enable; /* 0x00010C */
- bridgereg_t _pad_000110;
- bridgereg_t b_int_rst_stat; /* 0x000114 */
- bridgereg_t _pad_000118;
- bridgereg_t b_int_mode; /* 0x00011C */
- bridgereg_t _pad_000120;
- bridgereg_t b_int_device; /* 0x000124 */
- bridgereg_t _pad_000128;
- bridgereg_t b_int_host_err; /* 0x00012C */
+ u32 _pad_000100;
+ u32 b_int_status; /* 0x000104 */
+ u32 _pad_000108;
+ u32 b_int_enable; /* 0x00010C */
+ u32 _pad_000110;
+ u32 b_int_rst_stat; /* 0x000114 */
+ u32 _pad_000118;
+ u32 b_int_mode; /* 0x00011C */
+ u32 _pad_000120;
+ u32 b_int_device; /* 0x000124 */
+ u32 _pad_000128;
+ u32 b_int_host_err; /* 0x00012C */
struct {
- bridgereg_t __pad; /* 0x0001{30,,,68} */
- bridgereg_t addr; /* 0x0001{34,,,6C} */
+ u32 __pad; /* 0x0001{30,,,68} */
+ u32 addr; /* 0x0001{34,,,6C} */
} b_int_addr[8]; /* 0x000130 */
- bridgereg_t _pad_000170[36];
+ u32 _pad_000170[36];
/* Device 0x000200-0x0003FF */
struct {
- bridgereg_t __pad; /* 0x0002{00,,,38} */
- bridgereg_t reg; /* 0x0002{04,,,3C} */
+ u32 __pad; /* 0x0002{00,,,38} */
+ u32 reg; /* 0x0002{04,,,3C} */
} b_device[8]; /* 0x000200 */
struct {
- bridgereg_t __pad; /* 0x0002{40,,,78} */
- bridgereg_t reg; /* 0x0002{44,,,7C} */
+ u32 __pad; /* 0x0002{40,,,78} */
+ u32 reg; /* 0x0002{44,,,7C} */
} b_wr_req_buf[8]; /* 0x000240 */
struct {
- bridgereg_t __pad; /* 0x0002{80,,,88} */
- bridgereg_t reg; /* 0x0002{84,,,8C} */
+ u32 __pad; /* 0x0002{80,,,88} */
+ u32 reg; /* 0x0002{84,,,8C} */
} b_rrb_map[2]; /* 0x000280 */
#define b_even_resp b_rrb_map[0].reg /* 0x000284 */
#define b_odd_resp b_rrb_map[1].reg /* 0x00028C */
- bridgereg_t _pad_000290;
- bridgereg_t b_resp_status; /* 0x000294 */
- bridgereg_t _pad_000298;
- bridgereg_t b_resp_clear; /* 0x00029C */
+ u32 _pad_000290;
+ u32 b_resp_status; /* 0x000294 */
+ u32 _pad_000298;
+ u32 b_resp_clear; /* 0x00029C */
- bridgereg_t _pad_0002A0[24];
+ u32 _pad_0002A0[24];
char _pad_000300[0x10000 - 0x000300];
/* Internal Address Translation Entry RAM 0x010000-0x0103FF */
union {
- bridge_ate_t wr; /* write-only */
+ u64 wr; /* write-only */
struct {
- bridgereg_t _p_pad;
- bridgereg_t rd; /* read-only */
+ u32 _p_pad;
+ u32 rd; /* read-only */
} hi;
} b_int_ate_ram[128];
@@ -192,8 +195,8 @@ typedef volatile struct bridge_s {
/* Internal Address Translation Entry RAM LOW 0x011000-0x0113FF */
struct {
- bridgereg_t _p_pad;
- bridgereg_t rd; /* read-only */
+ u32 _p_pad;
+ u32 rd; /* read-only */
} b_int_ate_ram_lo[128];
char _pad_011400[0x20000 - 0x011400];
@@ -212,7 +215,7 @@ typedef volatile struct bridge_s {
} f[8];
} b_type0_cfg_dev[8]; /* 0x020000 */
- /* PCI Type 1 Configuration Space 0x028000-0x028FFF */
+ /* PCI Type 1 Configuration Space 0x028000-0x028FFF */
union { /* make all access sizes available. */
u8 c[0x1000 / 1];
u16 s[0x1000 / 2];
@@ -233,7 +236,7 @@ typedef volatile struct bridge_s {
u8 _pad_030007[0x04fff8]; /* 0x030008-0x07FFFF */
/* External Address Translation Entry RAM 0x080000-0x0FFFFF */
- bridge_ate_t b_ext_ate_ram[0x10000];
+ u64 b_ext_ate_ram[0x10000];
/* Reserved 0x100000-0x1FFFFF */
char _pad_100000[0x200000-0x100000];
@@ -259,13 +262,13 @@ typedef volatile struct bridge_s {
u32 l[0x400000 / 4]; /* read-only */
u64 d[0x400000 / 8]; /* read-only */
} b_external_flash; /* 0xC00000 */
-} bridge_t;
+};
/*
* Field formats for Error Command Word and Auxiliary Error Command Word
* of bridge.
*/
-typedef struct bridge_err_cmdword_s {
+struct bridge_err_cmdword {
union {
u32 cmd_word;
struct {
@@ -282,7 +285,7 @@ typedef struct bridge_err_cmdword_s {
rsvd:8;
} berr_st;
} berr_un;
-} bridge_err_cmdword_t;
+};
#define berr_field berr_un.berr_st
#endif /* !__ASSEMBLY__ */
@@ -290,7 +293,7 @@ typedef struct bridge_err_cmdword_s {
/*
* The values of these macros can and should be crosschecked
* regularly against the offsets of the like-named fields
- * within the "bridge_t" structure above.
+ * within the bridge_regs structure above.
*/
/* Byte offset macros for Bridge internal registers */
@@ -797,49 +800,14 @@ typedef struct bridge_err_cmdword_s {
#define PCI64_ATTR_RMF_MASK 0x00ff000000000000
#define PCI64_ATTR_RMF_SHFT 48
-#ifndef __ASSEMBLY__
-/* Address translation entry for mapped pci32 accesses */
-typedef union ate_u {
- u64 ent;
- struct ate_s {
- u64 rmf:16;
- u64 addr:36;
- u64 targ:4;
- u64 reserved:3;
- u64 barrier:1;
- u64 prefetch:1;
- u64 precise:1;
- u64 coherent:1;
- u64 valid:1;
- } field;
-} ate_t;
-#endif /* !__ASSEMBLY__ */
-
-#define ATE_V 0x01
-#define ATE_CO 0x02
-#define ATE_PREC 0x04
-#define ATE_PREF 0x08
-#define ATE_BAR 0x10
-
-#define ATE_PFNSHIFT 12
-#define ATE_TIDSHIFT 8
-#define ATE_RMFSHIFT 48
-
-#define mkate(xaddr, xid, attr) ((xaddr) & 0x0000fffffffff000ULL) | \
- ((xid)<<ATE_TIDSHIFT) | \
- (attr)
-
-#define BRIDGE_INTERNAL_ATES 128
-
struct bridge_controller {
struct pci_controller pc;
struct resource mem;
struct resource io;
struct resource busn;
- bridge_t *base;
+ struct bridge_regs *base;
nasid_t nasid;
unsigned int widget_id;
- unsigned int irq_cpu;
u64 baddr;
unsigned int pci_int[8];
};
@@ -847,8 +815,14 @@ struct bridge_controller {
#define BRIDGE_CONTROLLER(bus) \
((struct bridge_controller *)((bus)->sysdata))
-extern void register_bridge_irq(unsigned int irq);
-extern int request_bridge_irq(struct bridge_controller *bc);
+#define bridge_read(bc, reg) __raw_readl(&bc->base->reg)
+#define bridge_write(bc, reg, val) __raw_writel(val, &bc->base->reg)
+#define bridge_set(bc, reg, val) \
+ __raw_writel(__raw_readl(&bc->base->reg) | (val), &bc->base->reg)
+#define bridge_clr(bc, reg, val) \
+ __raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg)
+
+extern int request_bridge_irq(struct bridge_controller *bc, int pin);
extern struct pci_ops bridge_pci_ops;
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 @@
#include <asm/pgtable-64.h>
#endif
+#include <asm/cmpxchg.h>
#include <asm/io.h>
#include <asm/pgtable-bits.h>
@@ -204,51 +205,11 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
* Make sure the buddy is global too (if it's !none,
* it better already be global)
*/
-#ifdef CONFIG_SMP
- /*
- * For SMP, multiple CPUs can race, so we need to do
- * this atomically.
- */
- unsigned long page_global = _PAGE_GLOBAL;
- unsigned long tmp;
-
- if (kernel_uses_llsc && R10000_LLSC_WAR) {
- __asm__ __volatile__ (
- " .set push \n"
- " .set arch=r4000 \n"
- " .set noreorder \n"
- "1:" __LL "%[tmp], %[buddy] \n"
- " bnez %[tmp], 2f \n"
- " or %[tmp], %[tmp], %[global] \n"
- __SC "%[tmp], %[buddy] \n"
- " beqzl %[tmp], 1b \n"
- " nop \n"
- "2: \n"
- " .set pop \n"
- : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
- : [global] "r" (page_global));
- } else if (kernel_uses_llsc) {
- loongson_llsc_mb();
- __asm__ __volatile__ (
- " .set push \n"
- " .set "MIPS_ISA_ARCH_LEVEL" \n"
- " .set noreorder \n"
- "1:" __LL "%[tmp], %[buddy] \n"
- " bnez %[tmp], 2f \n"
- " or %[tmp], %[tmp], %[global] \n"
- __SC "%[tmp], %[buddy] \n"
- " beqz %[tmp], 1b \n"
- " nop \n"
- "2: \n"
- " .set pop \n"
- : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
- : [global] "r" (page_global));
- loongson_llsc_mb();
- }
-#else /* !CONFIG_SMP */
- if (pte_none(*buddy))
- pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
-#endif /* CONFIG_SMP */
+# if defined(CONFIG_PHYS_ADDR_T_64BIT) && !defined(CONFIG_CPU_MIPS32)
+ cmpxchg64(&buddy->pte, 0, _PAGE_GLOBAL);
+# else
+ cmpxchg(&buddy->pte, 0, _PAGE_GLOBAL);
+# endif
}
#endif
}
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 {
int (*boot_secondary)(int cpu, struct task_struct *idle);
void (*smp_setup)(void);
void (*prepare_cpus)(unsigned int max_cpus);
+ void (*prepare_boot_cpu)(void);
#ifdef CONFIG_HOTPLUG_CPU
int (*cpu_disable)(void);
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 @@
#ifndef __ASSEMBLY__
-#define PS_UINT_CAST (unsigned long)
#define UINT64_CAST (unsigned long)
-#define HUBREG_CAST (volatile hubreg_t *)
-
#else /* __ASSEMBLY__ */
-#define PS_UINT_CAST
#define UINT64_CAST
-#define HUBREG_CAST
#endif /* __ASSEMBLY__ */
@@ -256,42 +251,23 @@
* Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
* They're always safe.
*/
-#define LOCAL_HUB_ADDR(_x) (HUBREG_CAST (IALIAS_BASE + (_x)))
-#define REMOTE_HUB_ADDR(_n, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \
- 0x800000 + (_x)))
-#ifdef CONFIG_SGI_IP27
-#define REMOTE_HUB_PI_ADDR(_n, _sn, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \
- 0x800000 + (_x)))
-#endif /* CONFIG_SGI_IP27 */
+#define LOCAL_HUB_ADDR(_x) (IALIAS_BASE + (_x))
+#define REMOTE_HUB_ADDR(_n, _x) ((NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x)))
#ifndef __ASSEMBLY__
-#define HUB_L(_a) *(_a)
-#define HUB_S(_a, _d) *(_a) = (_d)
+#define LOCAL_HUB_PTR(_x) ((u64 *)LOCAL_HUB_ADDR((_x)))
+#define REMOTE_HUB_PTR(_n, _x) ((u64 *)REMOTE_HUB_ADDR((_n), (_x)))
-#define LOCAL_HUB_L(_r) HUB_L(LOCAL_HUB_ADDR(_r))
-#define LOCAL_HUB_S(_r, _d) HUB_S(LOCAL_HUB_ADDR(_r), (_d))
-#define REMOTE_HUB_L(_n, _r) HUB_L(REMOTE_HUB_ADDR((_n), (_r)))
-#define REMOTE_HUB_S(_n, _r, _d) HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d))
-#define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
-#define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
+#define LOCAL_HUB_L(_r) __raw_readq(LOCAL_HUB_PTR(_r))
+#define LOCAL_HUB_S(_r, _d) __raw_writeq((_d), LOCAL_HUB_PTR(_r))
+#define REMOTE_HUB_L(_n, _r) __raw_readq(REMOTE_HUB_PTR((_n), (_r)))
+#define REMOTE_HUB_S(_n, _r, _d) __raw_writeq((_d), \
+ REMOTE_HUB_PTR((_n), (_r)))
#endif /* !__ASSEMBLY__ */
/*
- * The following macros are used to get to a hub/bridge register, given
- * the base of the register space.
- */
-#define HUB_REG_PTR(_base, _off) \
- (HUBREG_CAST((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
-
-#define HUB_REG_PTR_L(_base, _off) \
- HUB_L(HUB_REG_PTR((_base), (_off)))
-
-#define HUB_REG_PTR_S(_base, _off, _data) \
- HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
-
-/*
* Software structure locations -- permanently fixed
* See diagram in kldir.h
*/
@@ -387,44 +363,14 @@
#define SYMMON_STK_END(nasid) (SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size)
-/* loading symmon 4k below UNIX. the arcs loader needs the topaddr for a
- * relocatable program
- */
-#define UNIX_DEBUG_LOADADDR 0x300000
-#define SYMMON_LOADADDR(nasid) \
- TO_NODE(nasid, PHYS_TO_K0(UNIX_DEBUG_LOADADDR - 0x1000))
-
-#define FREEMEM_OFFSET(nasid) KLD_FREEMEM(nasid)->offset
-#define FREEMEM_ADDR(nasid) SYMMON_STK_END(nasid)
-/*
- * XXX
- * Fix this. FREEMEM_ADDR should be aware of if symmon is loaded.
- * Also, it should take into account what prom thinks to be a safe
- * address
- PHYS_TO_K0(NODE_OFFSET(nasid) + FREEMEM_OFFSET(nasid))
- */
-#define FREEMEM_SIZE(nasid) KLD_FREEMEM(nasid)->size
-
-#define PI_ERROR_OFFSET(nasid) KLD_PI_ERROR(nasid)->offset
-#define PI_ERROR_ADDR(nasid) \
- TO_NODE_UNCAC((nasid), PI_ERROR_OFFSET(nasid))
-#define PI_ERROR_SIZE(nasid) KLD_PI_ERROR(nasid)->size
-
#define NODE_OFFSET_TO_K0(_nasid, _off) \
PHYS_TO_K0((NODE_OFFSET(_nasid) + (_off)) | CAC_BASE)
#define NODE_OFFSET_TO_K1(_nasid, _off) \
TO_UNCAC((NODE_OFFSET(_nasid) + (_off)) | UNCAC_BASE)
-#define K0_TO_NODE_OFFSET(_k0addr) \
- ((__psunsigned_t)(_k0addr) & NODE_ADDRSPACE_MASK)
#define KERN_VARS_ADDR(nasid) KLD_KERN_VARS(nasid)->pointer
#define KERN_VARS_SIZE(nasid) KLD_KERN_VARS(nasid)->size
-#define KERN_XP_ADDR(nasid) KLD_KERN_XP(nasid)->pointer
-#define KERN_XP_SIZE(nasid) KLD_KERN_XP(nasid)->size
-
-#define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET)
-
#endif /* !__ASSEMBLY__ */
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 @@
#include <asm/sn/sn0/arch.h>
#endif
-typedef u64 hubreg_t;
-
#define cputonasid(cpu) (sn_cpu_info[(cpu)].p_nasid)
#define cputoslice(cpu) (sn_cpu_info[(cpu)].p_slice)
#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 @@
IIO_ITTE_PUT((nasid), HUB_PIO_MAP_TO_MEM, \
(bigwin), IIO_ITTE_INVALID_WIDGET, 0)
-#define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin))
+#define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_PTR((nasid), IIO_ITTE(bigwin))
/*
* 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 @@
#define CALIAS_BASE CAC_BASE
-
-
-#define BRIDGE_REG_PTR(_base, _off) ((volatile bridgereg_t *) \
- ((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
-
#define SN0_WIDGET_BASE(_nasid, _wid) (NODE_SWIN_BASE((_nasid), (_wid)))
/* 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 @@
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
*/
extern void local_flush_tlb_all(void);
-extern void local_flush_tlb_mm(struct mm_struct *mm);
extern void local_flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
extern void local_flush_tlb_kernel_range(unsigned long start,
@@ -23,6 +22,8 @@ extern void local_flush_tlb_page(struct vm_area_struct *vma,
unsigned long page);
extern void local_flush_tlb_one(unsigned long vaddr);
+#include <asm/mmu_context.h>
+
#ifdef CONFIG_SMP
extern void flush_tlb_all(void);
@@ -36,7 +37,7 @@ extern void flush_tlb_one(unsigned long vaddr);
#else /* CONFIG_SMP */
#define flush_tlb_all() local_flush_tlb_all()
-#define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
+#define flush_tlb_mm(mm) drop_mmu_context(mm)
#define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, end)
#define flush_tlb_kernel_range(vmaddr,end) \
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 @@
#define JZ4740_EMC_SDRAM_CTRL 0x80
-
static void __init jz4740_detect_mem(void)
{
void __iomem *jz_emc_base;
@@ -66,15 +65,22 @@ static unsigned long __init get_board_mach_type(const void *fdt)
void __init plat_mem_setup(void)
{
int offset;
+ void *dtb;
jz4740_reset_init();
- __dt_setup_arch(__dtb_start);
- offset = fdt_path_offset(__dtb_start, "/memory");
+ if (__dtb_start != __dtb_end)
+ dtb = __dtb_start;
+ else
+ dtb = (void *)fw_passed_dtb;
+
+ __dt_setup_arch(dtb);
+
+ offset = fdt_path_offset(dtb, "/memory");
if (offset < 0)
jz4740_detect_mem();
- mips_machtype = get_board_mach_type(__dtb_start);
+ mips_machtype = get_board_mach_type(dtb);
}
void __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)
static inline unsigned int decode_config5(struct cpuinfo_mips *c)
{
- unsigned int config5;
+ unsigned int config5, max_mmid_width;
+ unsigned long asid_mask;
config5 = read_c0_config5();
config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
+
+ if (cpu_has_mips_r6) {
+ if (!__builtin_constant_p(cpu_has_mmid) || cpu_has_mmid)
+ config5 |= MIPS_CONF5_MI;
+ else
+ config5 &= ~MIPS_CONF5_MI;
+ }
+
write_c0_config5(config5);
if (config5 & MIPS_CONF5_EVA)
@@ -894,6 +903,50 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
if (config5 & MIPS_CONF5_CRCP)
elf_hwcap |= HWCAP_MIPS_CRC32;
+ if (cpu_has_mips_r6) {
+ /* Ensure the write to config5 above takes effect */
+ back_to_back_c0_hazard();
+
+ /* Check whether we successfully enabled MMID support */
+ config5 = read_c0_config5();
+ if (config5 & MIPS_CONF5_MI)
+ c->options |= MIPS_CPU_MMID;
+
+ /*
+ * Warn if we've hardcoded cpu_has_mmid to a value unsuitable
+ * for the CPU we're running on, or if CPUs in an SMP system
+ * have inconsistent MMID support.
+ */
+ WARN_ON(!!cpu_has_mmid != !!(config5 & MIPS_CONF5_MI));
+
+ if (cpu_has_mmid) {
+ write_c0_memorymapid(~0ul);
+ back_to_back_c0_hazard();
+ asid_mask = read_c0_memorymapid();
+
+ /*
+ * We maintain a bitmap to track MMID allocation, and
+ * need a sensible upper bound on the size of that
+ * bitmap. The initial CPU with MMID support (I6500)
+ * supports 16 bit MMIDs, which gives us an 8KiB
+ * bitmap. The architecture recommends that hardware
+ * support 32 bit MMIDs, which would give us a 512MiB
+ * bitmap - that's too big in most cases.
+ *
+ * Cap MMID width at 16 bits for now & we can revisit
+ * this if & when hardware supports anything wider.
+ */
+ max_mmid_width = 16;
+ if (asid_mask > GENMASK(max_mmid_width - 1, 0)) {
+ pr_info("Capping MMID width at %d bits",
+ max_mmid_width);
+ asid_mask = GENMASK(max_mmid_width - 1, 0);
+ }
+
+ set_cpu_asid_mask(c, asid_mask);
+ }
+ }
+
return config5 & MIPS_CONF_M;
}
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)
void __init init_IRQ(void)
{
int i;
+ unsigned int order = get_order(IRQ_STACK_SIZE);
for (i = 0; i < NR_IRQS; i++)
irq_set_noprobe(i);
@@ -62,8 +63,7 @@ void __init init_IRQ(void)
arch_init_irq();
for_each_possible_cpu(i) {
- int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE;
- void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages);
+ void *s = (void *)__get_free_pages(GFP_KERNEL, order);
irq_stack[i] = s;
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)
sc_bit ? "True" : "False",
cm2_cmd[cmd_bits], sport_bits);
}
- pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error,
- cm2_causes[cause], buf);
+ pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error,
+ cm2_causes[cause], buf);
pr_err("CM_ADDR =%08llx\n", cm_addr);
pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]);
} 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);
static int __init mipsr2_init_debugfs(void)
{
- struct dentry *mipsr2_emul;
-
- if (!mips_debugfs_dir)
- return -ENODEV;
-
- mipsr2_emul = debugfs_create_file("r2_emul_stats", S_IRUGO,
- mips_debugfs_dir, NULL,
- &mipsr2_emul_fops);
- if (!mipsr2_emul)
- return -ENOMEM;
-
- mipsr2_emul = debugfs_create_file("r2_emul_stats_clear", S_IRUGO,
- mips_debugfs_dir, NULL,
- &mipsr2_clear_fops);
- if (!mipsr2_emul)
- return -ENOMEM;
-
+ debugfs_create_file("r2_emul_stats", S_IRUGO, mips_debugfs_dir, NULL,
+ &mipsr2_emul_fops);
+ debugfs_create_file("r2_emul_stats_clear", S_IRUGO, mips_debugfs_dir,
+ NULL, &mipsr2_clear_fops);
return 0;
}
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 = {
static int __init segments_info(void)
{
- struct dentry *segments;
-
- if (cpu_has_segments) {
- if (!mips_debugfs_dir)
- return -ENODEV;
-
- segments = debugfs_create_file("segments", S_IRUGO,
- mips_debugfs_dir, NULL,
- &segments_fops);
- if (!segments)
- return -ENOMEM;
- }
+ if (cpu_has_segments)
+ debugfs_create_file("segments", S_IRUGO, mips_debugfs_dir, NULL,
+ &segments_fops);
return 0;
}
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;
struct dentry *mips_debugfs_dir;
static int __init debugfs_mips(void)
{
- struct dentry *d;
-
- d = debugfs_create_dir("mips", NULL);
- if (!d)
- return -ENOMEM;
- mips_debugfs_dir = d;
+ mips_debugfs_dir = debugfs_create_dir("mips", NULL);
return 0;
}
arch_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 @@
#include <linux/atomic.h>
#include <asm/cpu.h>
+#include <asm/ginvt.h>
#include <asm/processor.h>
#include <asm/idle.h>
#include <asm/r4k-timer.h>
@@ -443,6 +444,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
/* preload SMP state for boot cpu */
void smp_prepare_boot_cpu(void)
{
+ if (mp_ops->prepare_boot_cpu)
+ mp_ops->prepare_boot_cpu();
set_cpu_possible(0, true);
set_cpu_online(0, true);
}
@@ -482,12 +485,21 @@ static void flush_tlb_all_ipi(void *info)
void flush_tlb_all(void)
{
+ if (cpu_has_mmid) {
+ htw_stop();
+ ginvt_full();
+ sync_ginv();
+ instruction_hazard();
+ htw_start();
+ return;
+ }
+
on_each_cpu(flush_tlb_all_ipi, NULL, 1);
}
static void flush_tlb_mm_ipi(void *mm)
{
- local_flush_tlb_mm((struct mm_struct *)mm);
+ drop_mmu_context((struct mm_struct *)mm);
}
/*
@@ -530,17 +542,22 @@ void flush_tlb_mm(struct mm_struct *mm)
{
preempt_disable();
- if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
+ if (cpu_has_mmid) {
+ /*
+ * No need to worry about other CPUs - the ginvt in
+ * drop_mmu_context() will be globalized.
+ */
+ } else if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
smp_on_other_tlbs(flush_tlb_mm_ipi, mm);
} else {
unsigned int cpu;
for_each_online_cpu(cpu) {
if (cpu != smp_processor_id() && cpu_context(cpu, mm))
- cpu_context(cpu, mm) = 0;
+ set_cpu_context(cpu, mm, 0);
}
}
- local_flush_tlb_mm(mm);
+ drop_mmu_context(mm);
preempt_enable();
}
@@ -561,9 +578,26 @@ static void flush_tlb_range_ipi(void *info)
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
{
struct mm_struct *mm = vma->vm_mm;
+ unsigned long addr;
+ u32 old_mmid;
preempt_disable();
- if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
+ if (cpu_has_mmid) {
+ htw_stop();
+ old_mmid = read_c0_memorymapid();
+ write_c0_memorymapid(cpu_asid(0, mm));
+ mtc0_tlbw_hazard();
+ addr = round_down(start, PAGE_SIZE * 2);
+ end = round_up(end, PAGE_SIZE * 2);
+ do {
+ ginvt_va_mmid(addr);
+ sync_ginv();
+ addr += PAGE_SIZE * 2;
+ } while (addr < end);
+ write_c0_memorymapid(old_mmid);
+ instruction_hazard();
+ htw_start();
+ } else if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
struct flush_tlb_data fd = {
.vma = vma,
.addr1 = start,
@@ -571,6 +605,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l
};
smp_on_other_tlbs(flush_tlb_range_ipi, &fd);
+ local_flush_tlb_range(vma, start, end);
} else {
unsigned int cpu;
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
* mm has been completely unused by that CPU.
*/
if (cpu != smp_processor_id() && cpu_context(cpu, mm))
- cpu_context(cpu, mm) = !exec;
+ set_cpu_context(cpu, mm, !exec);
}
+ local_flush_tlb_range(vma, start, end);
}
- local_flush_tlb_range(vma, start, end);
preempt_enable();
}
@@ -616,14 +651,28 @@ static void flush_tlb_page_ipi(void *info)
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
+ u32 old_mmid;
+
preempt_disable();
- if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) {
+ if (cpu_has_mmid) {
+ htw_stop();
+ old_mmid = read_c0_memorymapid();
+ write_c0_memorymapid(cpu_asid(0, vma->vm_mm));
+ mtc0_tlbw_hazard();
+ ginvt_va_mmid(page);
+ sync_ginv();
+ write_c0_memorymapid(old_mmid);
+ instruction_hazard();
+ htw_start();
+ } else if ((atomic_read(&vma->vm_mm->mm_users) != 1) ||
+ (current->mm != vma->vm_mm)) {
struct flush_tlb_data fd = {
.vma = vma,
.addr1 = page,
};
smp_on_other_tlbs(flush_tlb_page_ipi, &fd);
+ local_flush_tlb_page(vma, page);
} else {
unsigned int cpu;
@@ -635,10 +684,10 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
* by that CPU.
*/
if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm))
- cpu_context(cpu, vma->vm_mm) = 1;
+ set_cpu_context(cpu, vma->vm_mm, 1);
}
+ local_flush_tlb_page(vma, page);
}
- local_flush_tlb_page(vma, page);
preempt_enable();
}
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");
static int __init spinlock_test(void)
{
- struct dentry *d;
-
- if (!mips_debugfs_dir)
- return -ENODEV;
-
- d = debugfs_create_file("spin_single", S_IRUGO,
- mips_debugfs_dir, NULL,
- &fops_ss);
- if (!d)
- return -ENOMEM;
-
- d = debugfs_create_file("spin_multi", S_IRUGO,
- mips_debugfs_dir, NULL,
- &fops_multi);
- if (!d)
- return -ENOMEM;
-
+ debugfs_create_file("spin_single", S_IRUGO, mips_debugfs_dir, NULL,
+ &fops_ss);
+ debugfs_create_file("spin_multi", S_IRUGO, mips_debugfs_dir, NULL,
+ &fops_multi);
return 0;
}
device_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)
cp0_fdc_irq = -1;
}
- if (!cpu_data[cpu].asid_cache)
+ if (cpu_has_mmid)
+ cpu_data[cpu].asid_cache = 0;
+ else if (!cpu_data[cpu].asid_cache)
cpu_data[cpu].asid_cache = asid_first_version(cpu);
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 @@
#include <asm/fpu.h>
#include <asm/fpu_emulator.h>
#include <asm/inst.h>
+#include <asm/mmu_context.h>
#include <linux/uaccess.h>
#define STR(x) __STR(x)
@@ -2374,18 +2375,10 @@ sigbus:
#ifdef CONFIG_DEBUG_FS
static int __init debugfs_unaligned(void)
{
- struct dentry *d;
-
- if (!mips_debugfs_dir)
- return -ENODEV;
- d = debugfs_create_u32("unaligned_instructions", S_IRUGO,
- mips_debugfs_dir, &unaligned_instructions);
- if (!d)
- return -ENOMEM;
- d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
- mips_debugfs_dir, &unaligned_action);
- if (!d)
- return -ENOMEM;
+ debugfs_create_u32("unaligned_instructions", S_IRUGO, mips_debugfs_dir,
+ &unaligned_instructions);
+ debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
+ mips_debugfs_dir, &unaligned_action);
return 0;
}
arch_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,
*/
preempt_disable();
cpu = smp_processor_id();
- get_new_mmu_context(kern_mm, cpu);
+ get_new_mmu_context(kern_mm);
for_each_possible_cpu(i)
if (i != cpu)
- cpu_context(i, kern_mm) = 0;
+ set_cpu_context(i, kern_mm, 0);
preempt_enable();
}
kvm_write_c0_guest_entryhi(cop0, entryhi);
@@ -1090,8 +1090,8 @@ static void kvm_mips_invalidate_guest_tlb(struct kvm_vcpu *vcpu,
if (i == cpu)
continue;
if (user)
- cpu_context(i, user_mm) = 0;
- cpu_context(i, kern_mm) = 0;
+ set_cpu_context(i, user_mm, 0);
+ set_cpu_context(i, kern_mm, 0);
}
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)
{
int ret;
+ if (cpu_has_mmid) {
+ pr_warn("KVM does not yet support MMIDs. KVM Disabled\n");
+ return -EOPNOTSUPP;
+ }
+
ret = kvm_mips_entry_setup();
if (ret)
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)
*/
if (current->flags & PF_VCPU) {
mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm;
- if ((cpu_context(cpu, mm) ^ asid_cache(cpu)) &
- asid_version_mask(cpu))
- get_new_mmu_context(mm, cpu);
- write_c0_entryhi(cpu_asid(cpu, mm));
- TLBMISS_HANDLER_SETUP_PGD(mm->pgd);
+ check_switch_mmu_context(mm);
kvm_mips_suspend_mm(cpu);
ehb();
}
@@ -1074,11 +1070,7 @@ static int kvm_trap_emul_vcpu_put(struct kvm_vcpu *vcpu, int cpu)
if (current->flags & PF_VCPU) {
/* Restore normal Linux process memory map */
- if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) &
- asid_version_mask(cpu)))
- get_new_mmu_context(current->mm, cpu);
- write_c0_entryhi(cpu_asid(cpu, current->mm));
- TLBMISS_HANDLER_SETUP_PGD(current->mm->pgd);
+ check_switch_mmu_context(current->mm);
kvm_mips_resume_mm(cpu);
ehb();
}
@@ -1106,14 +1098,14 @@ static void kvm_trap_emul_check_requests(struct kvm_vcpu *vcpu, int cpu,
kvm_mips_flush_gva_pt(kern_mm->pgd, KMF_GPA | KMF_KERN);
kvm_mips_flush_gva_pt(user_mm->pgd, KMF_GPA | KMF_USER);
for_each_possible_cpu(i) {
- cpu_context(i, kern_mm) = 0;
- cpu_context(i, user_mm) = 0;
+ set_cpu_context(i, kern_mm, 0);
+ set_cpu_context(i, user_mm, 0);
}
/* Generate new ASID for current mode */
if (reload_asid) {
mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm;
- get_new_mmu_context(mm, cpu);
+ get_new_mmu_context(mm);
htw_stop();
write_c0_entryhi(cpu_asid(cpu, mm));
TLBMISS_HANDLER_SETUP_PGD(mm->pgd);
@@ -1219,7 +1211,7 @@ static void kvm_trap_emul_vcpu_reenter(struct kvm_run *run,
if (gasid != vcpu->arch.last_user_gasid) {
kvm_mips_flush_gva_pt(user_mm->pgd, KMF_USER);
for_each_possible_cpu(i)
- cpu_context(i, user_mm) = 0;
+ set_cpu_context(i, user_mm, 0);
vcpu->arch.last_user_gasid = gasid;
}
}
@@ -1228,9 +1220,7 @@ static void kvm_trap_emul_vcpu_reenter(struct kvm_run *run,
* Check if ASID is stale. This may happen due to a TLB flush request or
* a lazy user MM invalidation.
*/
- if ((cpu_context(cpu, mm) ^ asid_cache(cpu)) &
- asid_version_mask(cpu))
- get_new_mmu_context(mm, cpu);
+ check_mmu_context(mm);
}
static 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)
cpu = smp_processor_id();
/* Restore normal Linux process memory map */
- if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) &
- asid_version_mask(cpu)))
- get_new_mmu_context(current->mm, cpu);
- write_c0_entryhi(cpu_asid(cpu, current->mm));
- TLBMISS_HANDLER_SETUP_PGD(current->mm->pgd);
+ check_switch_mmu_context(current->mm);
kvm_mips_resume_mm(cpu);
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)
* Root ASID dealiases guest GPA mappings in the root TLB.
* Allocate new root ASID if needed.
*/
- if (cpumask_test_and_clear_cpu(cpu, &kvm->arch.asid_flush_mask)
- || (cpu_context(cpu, gpa_mm) ^ asid_cache(cpu)) &
- asid_version_mask(cpu))
- get_new_mmu_context(gpa_mm, cpu);
+ if (cpumask_test_and_clear_cpu(cpu, &kvm->arch.asid_flush_mask))
+ get_new_mmu_context(gpa_mm);
+ else
+ check_mmu_context(gpa_mm);
}
}
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
bool "PCI Support"
depends on SOC_XWAY && PCI
-config XRX200_PHY_FW
- bool "XRX200 PHY firmware loader"
- depends on SOC_XWAY
-
endif
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 @@
#include <asm/hazards.h>
#include <asm/mipsregs.h>
+#include <asm/mmu_context.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/tlbdebug.h>
@@ -73,12 +74,13 @@ static inline const char *msk2str(unsigned int mask)
static void dump_tlb(int first, int last)
{
- unsigned long s_entryhi, entryhi, asid;
+ unsigned long s_entryhi, entryhi, asid, mmid;
unsigned long long entrylo0, entrylo1, pa;
unsigned int s_index, s_pagemask, s_guestctl1 = 0;
unsigned int pagemask, guestctl1 = 0, c0, c1, i;
unsigned long asidmask = cpu_asid_mask(&current_cpu_data);
int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4);
+ unsigned long uninitialized_var(s_mmid);
#ifdef CONFIG_32BIT
bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA);
int pwidth = xpa ? 11 : 8;
@@ -92,7 +94,12 @@ static void dump_tlb(int first, int last)
s_pagemask = read_c0_pagemask();
s_entryhi = read_c0_entryhi();
s_index = read_c0_index();
- asid = s_entryhi & asidmask;
+
+ if (cpu_has_mmid)
+ asid = s_mmid = read_c0_memorymapid();
+ else
+ asid = s_entryhi & asidmask;
+
if (cpu_has_guestid)
s_guestctl1 = read_c0_guestctl1();
@@ -105,6 +112,12 @@ static void dump_tlb(int first, int last)
entryhi = read_c0_entryhi();
entrylo0 = read_c0_entrylo0();
entrylo1 = read_c0_entrylo1();
+
+ if (cpu_has_mmid)
+ mmid = read_c0_memorymapid();
+ else
+ mmid = entryhi & asidmask;
+
if (cpu_has_guestid)
guestctl1 = read_c0_guestctl1();
@@ -124,8 +137,7 @@ static void dump_tlb(int first, int last)
* leave only a single G bit set after a machine check exception
* due to duplicate TLB entry.
*/
- if (!((entrylo0 | entrylo1) & ENTRYLO_G) &&
- (entryhi & asidmask) != asid)
+ if (!((entrylo0 | entrylo1) & ENTRYLO_G) && (mmid != asid))
continue;
/*
@@ -138,7 +150,7 @@ static void dump_tlb(int first, int last)
pr_cont("va=%0*lx asid=%0*lx",
vwidth, (entryhi & ~0x1fffUL),
- asidwidth, entryhi & asidmask);
+ asidwidth, mmid);
if (cpu_has_guestid)
pr_cont(" gid=%02lx",
(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
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_HIGHMEM
- select SYS_SUPPORTS_MIPS16
select SYS_HAS_EARLY_PRINTK
select USE_GENERIC_EARLY_PRINTK_8250
select COMMON_CLK
@@ -31,7 +30,6 @@ config LOONGSON1_LS1C
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_HIGHMEM
- select SYS_SUPPORTS_MIPS16
select SYS_HAS_EARLY_PRINTK
select USE_GENERIC_EARLY_PRINTK_8250
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 @@
-cflags-$(CONFIG_CPU_LOONGSON1) += -march=mips32 -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON1) += -march=mips32r2 -Wa,--trap
platform-$(CONFIG_MACH_LOONGSON32) += loongson32/
cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32
-load-$(CONFIG_CPU_LOONGSON1) += 0xffffffff80100000
+load-$(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 = {
},
};
-/* DMA */
-static struct resource ls1x_dma_resources[] = {
- [0] = {
- .start = LS1X_DMAC_BASE,
- .end = LS1X_DMAC_BASE + SZ_4 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = LS1X_DMA0_IRQ,
- .end = LS1X_DMA0_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = LS1X_DMA1_IRQ,
- .end = LS1X_DMA1_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- .start = LS1X_DMA2_IRQ,
- .end = LS1X_DMA2_IRQ,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device ls1x_dma_pdev = {
- .name = "ls1x-dma",
- .id = -1,
- .num_resources = ARRAY_SIZE(ls1x_dma_resources),
- .resource = ls1x_dma_resources,
-};
-
-void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata)
-{
- ls1x_dma_pdev.dev.platform_data = pdata;
-}
-
/* Synopsys Ethernet GMAC */
static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
.phy_mask = 0,
@@ -291,33 +255,6 @@ struct platform_device ls1x_gpio1_pdev = {
.resource = ls1x_gpio1_resources,
};
-/* NAND Flash */
-static struct resource ls1x_nand_resources[] = {
- [0] = {
- .start = LS1X_NAND_BASE,
- .end = LS1X_NAND_BASE + SZ_32 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- /* DMA channel 0 is dedicated to NAND */
- .start = LS1X_DMA_CHANNEL0,
- .end = LS1X_DMA_CHANNEL0,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device ls1x_nand_pdev = {
- .name = "ls1x-nand",
- .id = -1,
- .num_resources = ARRAY_SIZE(ls1x_nand_resources),
- .resource = ls1x_nand_resources,
-};
-
-void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata)
-{
- ls1x_nand_pdev.dev.platform_data = pdata;
-}
-
/* USB EHCI */
static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32);
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 @@
#include <nand.h>
#include <platform.h>
-struct plat_ls1x_dma ls1x_dma_pdata = {
- .nr_channels = 3,
-};
-
-static struct mtd_partition ls1x_nand_parts[] = {
- {
- .name = "kernel",
- .offset = 0,
- .size = SZ_16M,
- },
- {
- .name = "rootfs",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-struct plat_ls1x_nand ls1x_nand_pdata = {
- .parts = ls1x_nand_parts,
- .nr_parts = ARRAY_SIZE(ls1x_nand_parts),
- .hold_cycle = 0x2,
- .wait_cycle = 0xc,
-};
-
static const struct gpio_led ls1x_gpio_leds[] __initconst = {
{
.name = "LED9",
@@ -64,13 +40,11 @@ static const struct gpio_led_platform_data ls1x_led_pdata __initconst = {
static struct platform_device *ls1b_platform_devices[] __initdata = {
&ls1x_uart_pdev,
&ls1x_cpufreq_pdev,
- &ls1x_dma_pdev,
&ls1x_eth0_pdev,
&ls1x_eth1_pdev,
&ls1x_ehci_pdev,
&ls1x_gpio0_pdev,
&ls1x_gpio1_pdev,
- &ls1x_nand_pdev,
&ls1x_rtc_pdev,
&ls1x_wdt_pdev,
};
@@ -78,8 +52,6 @@ static struct platform_device *ls1b_platform_devices[] __initdata = {
static int __init ls1b_platform_init(void)
{
ls1x_serial_set_uartclk(&ls1x_uart_pdev);
- ls1x_dma_set_platdata(&ls1x_dma_pdata);
- ls1x_nand_set_platdata(&ls1x_nand_pdata);
gpio_led_register_device(-1, &ls1x_led_pdata);
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)
{
struct dentry *fpuemu_debugfs_base_dir;
struct dentry *fpuemu_debugfs_inst_dir;
- struct dentry *d, *reset_file;
-
- if (!mips_debugfs_dir)
- return -ENODEV;
fpuemu_debugfs_base_dir = debugfs_create_dir("fpuemustats",
mips_debugfs_dir);
- if (!fpuemu_debugfs_base_dir)
- return -ENOMEM;
- reset_file = debugfs_create_file("fpuemustats_clear", 0444,
- mips_debugfs_dir, NULL,
- &fpuemustats_clear_fops);
- if (!reset_file)
- return -ENOMEM;
+ debugfs_create_file("fpuemustats_clear", 0444, mips_debugfs_dir, NULL,
+ &fpuemustats_clear_fops);
#define FPU_EMU_STAT_OFFSET(m) \
offsetof(struct mips_fpu_emulator_stats, m)
#define FPU_STAT_CREATE(m) \
do { \
- d = debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \
+ debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \
(void *)FPU_EMU_STAT_OFFSET(m), \
&fops_fpuemu_stat); \
- if (!d) \
- return -ENOMEM; \
} while (0)
FPU_STAT_CREATE(emulated);
@@ -233,8 +222,6 @@ do { \
fpuemu_debugfs_inst_dir = debugfs_create_dir("instructions",
fpuemu_debugfs_base_dir);
- if (!fpuemu_debugfs_inst_dir)
- return -ENOMEM;
#define FPU_STAT_CREATE_EX(m) \
do { \
@@ -242,11 +229,9 @@ do { \
\
adjust_instruction_counter_name(name, #m); \
\
- d = debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \
+ debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \
(void *)FPU_EMU_STAT_OFFSET(m), \
&fops_fpuemu_stat); \
- if (!d) \
- return -ENOMEM; \
} while (0)
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 @@
# Makefile for the Linux/MIPS-specific parts of the memory manager.
#
-obj-y += cache.o extable.o fault.o \
- gup.o init.o mmap.o page.o page-funcs.o \
- pgtable.o tlbex.o tlbex-fault.o tlb-funcs.o
+obj-y += cache.o
+obj-y += context.o
+obj-y += extable.o
+obj-y += fault.o
+obj-y += gup.o
+obj-y += init.o
+obj-y += mmap.o
+obj-y += page.o
+obj-y += page-funcs.o
+obj-y += pgtable.o
+obj-y += tlbex.o
+obj-y += tlbex-fault.o
+obj-y += tlb-funcs.o
ifdef CONFIG_CPU_MICROMIPS
obj-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)
/**
- * Flush the icache for a trampoline. These are used for interrupt
- * and exception hooking.
- *
- * @addr: Address to flush
- */
-static void octeon_flush_cache_sigtramp(unsigned long addr)
-{
- struct vm_area_struct *vma;
-
- down_read(&current->mm->mmap_sem);
- vma = find_vma(current->mm, addr);
- octeon_flush_icache_all_cores(vma);
- up_read(&current->mm->mmap_sem);
-}
-
-
-/**
* Flush a range out of a vma
*
* @vma: VMA to flush
@@ -289,7 +272,6 @@ void octeon_cache_init(void)
flush_cache_mm = octeon_flush_cache_mm;
flush_cache_page = octeon_flush_cache_page;
flush_cache_range = octeon_flush_cache_range;
- flush_cache_sigtramp = octeon_flush_cache_sigtramp;
flush_icache_all = octeon_flush_icache_all;
flush_data_cache_page = octeon_flush_data_cache_page;
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)
{
}
-static void r3k_flush_cache_sigtramp(unsigned long addr)
-{
- unsigned long flags;
-
- pr_debug("csigtramp[%08lx]\n", addr);
-
- flags = read_c0_status();
-
- write_c0_status(flags&~ST0_IEC);
-
- /* Fill the TLB to avoid an exception with caches isolated. */
- asm( "lw\t$0, 0x000(%0)\n\t"
- "lw\t$0, 0x004(%0)\n\t"
- : : "r" (addr) );
-
- write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
-
- asm( "sb\t$0, 0x000(%0)\n\t"
- "sb\t$0, 0x004(%0)\n\t"
- : : "r" (addr) );
-
- write_c0_status(flags);
-}
-
static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size)
{
BUG();
@@ -331,7 +307,6 @@ void r3k_cache_init(void)
__flush_kernel_vmap_range = r3k_flush_kernel_vmap_range;
- flush_cache_sigtramp = r3k_flush_cache_sigtramp;
local_flush_data_cache_page = local_r3k_flush_data_cache_page;
flush_data_cache_page = r3k_flush_data_cache_page;
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)
unsigned int i;
const cpumask_t *mask = cpu_present_mask;
+ if (cpu_has_mmid)
+ return cpu_context(0, mm) != 0;
+
/* cpu_sibling_map[] undeclared when !CONFIG_SMP */
#ifdef CONFIG_SMP
/*
@@ -697,10 +700,7 @@ static inline void local_r4k_flush_cache_page(void *args)
}
if (exec) {
if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
- int cpu = smp_processor_id();
-
- if (cpu_context(cpu, mm) != 0)
- drop_mmu_context(mm, cpu);
+ drop_mmu_context(mm);
} else
vaddr ? r4k_blast_icache_page(addr) :
r4k_blast_icache_user_page(addr);
@@ -937,119 +937,6 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
}
#endif /* CONFIG_DMA_NONCOHERENT */
-struct flush_cache_sigtramp_args {
- struct mm_struct *mm;
- struct page *page;
- unsigned long addr;
-};
-
-/*
- * While we're protected against bad userland addresses we don't care
- * very much about what happens in that case. Usually a segmentation
- * fault will dump the process later on anyway ...
- */
-static void local_r4k_flush_cache_sigtramp(void *args)
-{
- struct flush_cache_sigtramp_args *fcs_args = args;
- unsigned long addr = fcs_args->addr;
- struct page *page = fcs_args->page;
- struct mm_struct *mm = fcs_args->mm;
- int map_coherent = 0;
- void *vaddr;
-
- unsigned long ic_lsize = cpu_icache_line_size();
- unsigned long dc_lsize = cpu_dcache_line_size();
- unsigned long sc_lsize = cpu_scache_line_size();
-
- /*
- * If owns no valid ASID yet, cannot possibly have gotten
- * this page into the cache.
- */
- if (!has_valid_asid(mm, R4K_HIT))
- return;
-
- if (mm == current->active_mm) {
- vaddr = NULL;
- } else {
- /*
- * Use kmap_coherent or kmap_atomic to do flushes for
- * another ASID than the current one.
- */
- map_coherent = (cpu_has_dc_aliases &&
- page_mapcount(page) &&
- !Page_dcache_dirty(page));
- if (map_coherent)
- vaddr = kmap_coherent(page, addr);
- else
- vaddr = kmap_atomic(page);
- addr = (unsigned long)vaddr + (addr & ~PAGE_MASK);
- }
-
- R4600_HIT_CACHEOP_WAR_IMPL;
- if (!cpu_has_ic_fills_f_dc) {
- if (dc_lsize)
- vaddr ? flush_dcache_line(addr & ~(dc_lsize - 1))
- : protected_writeback_dcache_line(
- addr & ~(dc_lsize - 1));
- if (!cpu_icache_snoops_remote_store && scache_size)
- vaddr ? flush_scache_line(addr & ~(sc_lsize - 1))
- : protected_writeback_scache_line(
- addr & ~(sc_lsize - 1));
- }
- if (ic_lsize)
- vaddr ? flush_icache_line(addr & ~(ic_lsize - 1))
- : protected_flush_icache_line(addr & ~(ic_lsize - 1));
-
- if (vaddr) {
- if (map_coherent)
- kunmap_coherent();
- else
- kunmap_atomic(vaddr);
- }
-
- if (MIPS4K_ICACHE_REFILL_WAR) {
- __asm__ __volatile__ (
- ".set push\n\t"
- ".set noat\n\t"
- ".set "MIPS_ISA_LEVEL"\n\t"
-#ifdef CONFIG_32BIT
- "la $at,1f\n\t"
-#endif
-#ifdef CONFIG_64BIT
- "dla $at,1f\n\t"
-#endif
- "cache %0,($at)\n\t"
- "nop; nop; nop\n"
- "1:\n\t"
- ".set pop"
- :
- : "i" (Hit_Invalidate_I));
- }
- if (MIPS_CACHE_SYNC_WAR)
- __asm__ __volatile__ ("sync");
-}
-
-static void r4k_flush_cache_sigtramp(unsigned long addr)
-{
- struct flush_cache_sigtramp_args args;
- int npages;
-
- down_read(&current->mm->mmap_sem);
-
- npages = get_user_pages_fast(addr, 1, 0, &args.page);
- if (npages < 1)
- goto out;
-
- args.mm = current->mm;
- args.addr = addr;
-
- r4k_on_each_cpu(R4K_HIT, local_r4k_flush_cache_sigtramp, &args);
-
- put_page(args.page);
-out:
- up_read(&current->mm->mmap_sem);
-}
-
static void r4k_flush_icache_all(void)
{
if (cpu_has_vtag_icache)
@@ -1978,7 +1865,6 @@ void r4k_cache_init(void)
__flush_kernel_vmap_range = r4k_flush_kernel_vmap_range;
- flush_cache_sigtramp = r4k_flush_cache_sigtramp;
flush_icache_all = r4k_flush_icache_all;
local_flush_data_cache_page = local_r4k_flush_data_cache_page;
flush_data_cache_page = r4k_flush_data_cache_page;
@@ -2033,7 +1919,6 @@ void r4k_cache_init(void)
/* I$ fills from D$ just by emptying the write buffers */
flush_cache_page = (void *)b5k_instruction_hazard;
flush_cache_range = (void *)b5k_instruction_hazard;
- flush_cache_sigtramp = (void *)b5k_instruction_hazard;
local_flush_data_cache_page = (void *)b5k_instruction_hazard;
flush_data_cache_page = (void *)b5k_instruction_hazard;
flush_icache_range = (void *)b5k_instruction_hazard;
@@ -2052,7 +1937,6 @@ void r4k_cache_init(void)
flush_cache_mm = (void *)cache_noop;
flush_cache_page = (void *)cache_noop;
flush_cache_range = (void *)cache_noop;
- flush_cache_sigtramp = (void *)cache_noop;
flush_icache_all = (void *)cache_noop;
flush_data_cache_page = (void *)cache_noop;
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)
}
}
-static void tx39_flush_cache_sigtramp(unsigned long addr)
-{
- unsigned long ic_lsize = current_cpu_data.icache.linesz;
- unsigned long dc_lsize = current_cpu_data.dcache.linesz;
- unsigned long config;
- unsigned long flags;
-
- protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
-
- /* disable icache (set ICE#) */
- local_irq_save(flags);
- config = read_c0_conf();
- write_c0_conf(config & ~TX39_CONF_ICE);
- TX39_STOP_STREAMING();
- protected_flush_icache_line(addr & ~(ic_lsize - 1));
- write_c0_conf(config);
- local_irq_restore(flags);
-}
-
static __init void tx39_probe_cache(void)
{
unsigned long config;
@@ -368,7 +349,6 @@ void tx39_cache_init(void)
flush_icache_range = (void *) tx39h_flush_icache_all;
local_flush_icache_range = (void *) tx39h_flush_icache_all;
- flush_cache_sigtramp = (void *) tx39h_flush_icache_all;
local_flush_data_cache_page = (void *) tx39h_flush_icache_all;
flush_data_cache_page = (void *) tx39h_flush_icache_all;
@@ -397,7 +377,6 @@ void tx39_cache_init(void)
__flush_kernel_vmap_range = tx39_flush_kernel_vmap_range;
- flush_cache_sigtramp = tx39_flush_cache_sigtramp;
local_flush_data_cache_page = local_tx39_flush_data_cache_page;
flush_data_cache_page = tx39_flush_data_cache_page;
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);
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
/* MIPS specific cache operations */
-void (*flush_cache_sigtramp)(unsigned long addr);
void (*local_flush_data_cache_page)(void * addr);
void (*flush_data_cache_page)(unsigned long addr);
void (*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 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/atomic.h>
+#include <linux/mmu_context.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+
+static DEFINE_RAW_SPINLOCK(cpu_mmid_lock);
+
+static atomic64_t mmid_version;
+static unsigned int num_mmids;
+static unsigned long *mmid_map;
+
+static DEFINE_PER_CPU(u64, reserved_mmids);
+static cpumask_t tlb_flush_pending;
+
+static bool asid_versions_eq(int cpu, u64 a, u64 b)
+{
+ return ((a ^ b) & asid_version_mask(cpu)) == 0;
+}
+
+void get_new_mmu_context(struct mm_struct *mm)
+{
+ unsigned int cpu;
+ u64 asid;
+
+ /*
+ * This function is specific to ASIDs, and should not be called when
+ * MMIDs are in use.
+ */
+ if (WARN_ON(IS_ENABLED(CONFIG_DEBUG_VM) && cpu_has_mmid))
+ return;
+
+ cpu = smp_processor_id();
+ asid = asid_cache(cpu);
+
+ if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) {
+ if (cpu_has_vtag_icache)
+ flush_icache_all();
+ local_flush_tlb_all(); /* start new asid cycle */
+ }
+
+ set_cpu_context(cpu, mm, asid);
+ asid_cache(cpu) = asid;
+}
+EXPORT_SYMBOL_GPL(get_new_mmu_context);
+
+void check_mmu_context(struct mm_struct *mm)
+{
+ unsigned int cpu = smp_processor_id();
+
+ /*
+ * This function is specific to ASIDs, and should not be called when
+ * MMIDs are in use.
+ */
+ if (WARN_ON(IS_ENABLED(CONFIG_DEBUG_VM) && cpu_has_mmid))
+ return;
+
+ /* Check if our ASID is of an older version and thus invalid */
+ if (!asid_versions_eq(cpu, cpu_context(cpu, mm), asid_cache(cpu)))
+ get_new_mmu_context(mm);
+}
+EXPORT_SYMBOL_GPL(check_mmu_context);
+
+static void flush_context(void)
+{
+ u64 mmid;
+ int cpu;
+
+ /* Update the list of reserved MMIDs and the MMID bitmap */
+ bitmap_clear(mmid_map, 0, num_mmids);
+
+ /* Reserve an MMID for kmap/wired entries */
+ __set_bit(MMID_KERNEL_WIRED, mmid_map);
+
+ for_each_possible_cpu(cpu) {
+ mmid = xchg_relaxed(&cpu_data[cpu].asid_cache, 0);
+
+ /*
+ * If this CPU has already been through a
+ * rollover, but hasn't run another task in
+ * the meantime, we must preserve its reserved
+ * MMID, as this is the only trace we have of
+ * the process it is still running.
+ */
+ if (mmid == 0)
+ mmid = per_cpu(reserved_mmids, cpu);
+
+ __set_bit(mmid & cpu_asid_mask(&cpu_data[cpu]), mmid_map);
+ per_cpu(reserved_mmids, cpu) = mmid;
+ }
+
+ /*
+ * Queue a TLB invalidation for each CPU to perform on next
+ * context-switch
+ */
+ cpumask_setall(&tlb_flush_pending);
+}
+
+static bool check_update_reserved_mmid(u64 mmid, u64 newmmid)
+{
+ bool hit;
+ int cpu;
+
+ /*
+ * Iterate over the set of reserved MMIDs looking for a match.
+ * If we find one, then we can update our mm to use newmmid
+ * (i.e. the same MMID in the current generation) but we can't
+ * exit the loop early, since we need to ensure that all copies
+ * of the old MMID are updated to reflect the mm. Failure to do
+ * so could result in us missing the reserved MMID in a future
+ * generation.
+ */
+ hit = false;
+ for_each_possible_cpu(cpu) {
+ if (per_cpu(reserved_mmids, cpu) == mmid) {
+ hit = true;
+ per_cpu(reserved_mmids, cpu) = newmmid;
+ }
+ }
+
+ return hit;
+}
+
+static u64 get_new_mmid(struct mm_struct *mm)
+{
+ static u32 cur_idx = MMID_KERNEL_WIRED + 1;
+ u64 mmid, version, mmid_mask;
+
+ mmid = cpu_context(0, mm);
+ version = atomic64_read(&mmid_version);
+ mmid_mask = cpu_asid_mask(&boot_cpu_data);
+
+ if (!asid_versions_eq(0, mmid, 0)) {
+ u64 newmmid = version | (mmid & mmid_mask);
+
+ /*
+ * If our current MMID was active during a rollover, we
+ * can continue to use it and this was just a false alarm.
+ */
+ if (check_update_reserved_mmid(mmid, newmmid)) {
+ mmid = newmmid;
+ goto set_context;
+ }
+
+ /*
+ * We had a valid MMID in a previous life, so try to re-use
+ * it if possible.
+ */
+ if (!__test_and_set_bit(mmid & mmid_mask, mmid_map)) {
+ mmid = newmmid;
+ goto set_context;
+ }
+ }
+
+ /* Allocate a free MMID */
+ mmid = find_next_zero_bit(mmid_map, num_mmids, cur_idx);
+ if (mmid != num_mmids)
+ goto reserve_mmid;
+
+ /* We're out of MMIDs, so increment the global version */
+ version = atomic64_add_return_relaxed(asid_first_version(0),
+ &mmid_version);
+
+ /* Note currently active MMIDs & mark TLBs as requiring flushes */
+ flush_context();
+
+ /* We have more MMIDs than CPUs, so this will always succeed */
+ mmid = find_first_zero_bit(mmid_map, num_mmids);
+
+reserve_mmid:
+ __set_bit(mmid, mmid_map);
+ cur_idx = mmid;
+ mmid |= version;
+set_context:
+ set_cpu_context(0, mm, mmid);
+ return mmid;
+}
+
+void check_switch_mmu_context(struct mm_struct *mm)
+{
+ unsigned int cpu = smp_processor_id();
+ u64 ctx, old_active_mmid;
+ unsigned long flags;
+
+ if (!cpu_has_mmid) {
+ check_mmu_context(mm);
+ write_c0_entryhi(cpu_asid(cpu, mm));
+ goto setup_pgd;
+ }
+
+ /*
+ * MMID switch fast-path, to avoid acquiring cpu_mmid_lock when it's
+ * unnecessary.
+ *
+ * The memory ordering here is subtle. If our active_mmids is non-zero
+ * and the MMID matches the current version, then we update the CPU's
+ * asid_cache with a relaxed cmpxchg. Racing with a concurrent rollover
+ * means that either:
+ *
+ * - We get a zero back from the cmpxchg and end up waiting on
+ * cpu_mmid_lock in check_mmu_context(). Taking the lock synchronises
+ * with the rollover and so we are forced to see the updated
+ * generation.
+ *
+ * - We get a valid MMID back from the cmpxchg, which means the
+ * relaxed xchg in flush_context will treat us as reserved
+ * because atomic RmWs are totally ordered for a given location.
+ */
+ ctx = cpu_context(cpu, mm);
+ old_active_mmid = READ_ONCE(cpu_data[cpu].asid_cache);
+ if (!old_active_mmid ||
+ !asid_versions_eq(cpu, ctx, atomic64_read(&mmid_version)) ||
+ !cmpxchg_relaxed(&cpu_data[cpu].asid_cache, old_active_mmid, ctx)) {
+ raw_spin_lock_irqsave(&cpu_mmid_lock, flags);
+
+ ctx = cpu_context(cpu, mm);
+ if (!asid_versions_eq(cpu, ctx, atomic64_read(&mmid_version)))
+ ctx = get_new_mmid(mm);
+
+ WRITE_ONCE(cpu_data[cpu].asid_cache, ctx);
+ raw_spin_unlock_irqrestore(&cpu_mmid_lock, flags);
+ }
+
+ /*
+ * Invalidate the local TLB if needed. Note that we must only clear our
+ * bit in tlb_flush_pending after this is complete, so that the
+ * cpu_has_shared_ftlb_entries case below isn't misled.
+ */
+ if (cpumask_test_cpu(cpu, &tlb_flush_pending)) {
+ if (cpu_has_vtag_icache)
+ flush_icache_all();
+ local_flush_tlb_all();
+ cpumask_clear_cpu(cpu, &tlb_flush_pending);
+ }
+
+ write_c0_memorymapid(ctx & cpu_asid_mask(&boot_cpu_data));
+
+ /*
+ * If this CPU shares FTLB entries with its siblings and one or more of
+ * those siblings hasn't yet invalidated its TLB following a version
+ * increase then we need to invalidate any TLB entries for our MMID
+ * that we might otherwise pick up from a sibling.
+ *
+ * We ifdef on CONFIG_SMP because cpu_sibling_map isn't defined in
+ * CONFIG_SMP=n kernels.
+ */
+#ifdef CONFIG_SMP
+ if (cpu_has_shared_ftlb_entries &&
+ cpumask_intersects(&tlb_flush_pending, &cpu_sibling_map[cpu])) {
+ /* Ensure we operate on the new MMID */
+ mtc0_tlbw_hazard();
+
+ /*
+ * Invalidate all TLB entries associated with the new
+ * MMID, and wait for the invalidation to complete.
+ */
+ ginvt_mmid();
+ sync_ginv();
+ }
+#endif
+
+setup_pgd:
+ TLBMISS_HANDLER_SETUP_PGD(mm->pgd);
+}
+EXPORT_SYMBOL_GPL(check_switch_mmu_context);
+
+static int mmid_init(void)
+{
+ if (!cpu_has_mmid)
+ return 0;
+
+ /*
+ * Expect allocation after rollover to fail if we don't have at least
+ * one more MMID than CPUs.
+ */
+ num_mmids = asid_first_version(0);
+ WARN_ON(num_mmids <= num_possible_cpus());
+
+ atomic64_set(&mmid_version, asid_first_version(0));
+ mmid_map = kcalloc(BITS_TO_LONGS(num_mmids), sizeof(*mmid_map),
+ GFP_KERNEL);
+ if (!mmid_map)
+ panic("Failed to allocate bitmap for %u MMIDs\n", num_mmids);
+
+ /* Reserve an MMID for kmap/wired entries */
+ __set_bit(MMID_KERNEL_WIRED, mmid_map);
+
+ pr_info("MMID allocator initialised with %u entries\n", num_mmids);
+ return 0;
+}
+early_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,
if (PageHighMem(page)) {
void *addr;
- if (offset + len > PAGE_SIZE) {
- if (offset >= PAGE_SIZE) {
- page += offset >> PAGE_SHIFT;
- offset &= ~PAGE_MASK;
- }
+ if (offset + len > PAGE_SIZE)
len = PAGE_SIZE - offset;
- }
addr = kmap_atomic(page);
dma_sync_virt(addr + offset, len, dir);
@@ -145,12 +140,14 @@ void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
dma_sync_phys(paddr, size, dir);
}
+#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
size_t size, enum dma_data_direction dir)
{
if (cpu_needs_post_dma_flush(dev))
dma_sync_phys(paddr, size, dir);
}
+#endif
void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
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)
static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
{
enum fixed_addresses idx;
+ unsigned int uninitialized_var(old_mmid);
unsigned long vaddr, flags, entrylo;
unsigned long old_ctx;
pte_t pte;
@@ -110,6 +111,10 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
write_c0_entryhi(vaddr & (PAGE_MASK << 1));
write_c0_entrylo0(entrylo);
write_c0_entrylo1(entrylo);
+ if (cpu_has_mmid) {
+ old_mmid = read_c0_memorymapid();
+ write_c0_memorymapid(MMID_KERNEL_WIRED);
+ }
#ifdef CONFIG_XPA
if (cpu_has_xpa) {
entrylo = (pte.pte_low & _PFNX_MASK);
@@ -124,6 +129,8 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
tlb_write_indexed();
tlbw_use_hazard();
write_c0_entryhi(old_ctx);
+ if (cpu_has_mmid)
+ write_c0_memorymapid(old_mmid);
local_irq_restore(flags);
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 = {
static int __init sc_debugfs_init(void)
{
- struct dentry *dir, *file;
-
- if (!mips_debugfs_dir)
- return -ENODEV;
+ struct dentry *dir;
dir = debugfs_create_dir("l2cache", mips_debugfs_dir);
- if (IS_ERR(dir))
- return PTR_ERR(dir);
-
- file = debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir,
- NULL, &sc_prefetch_fops);
- if (!file)
- return -ENOMEM;
-
+ debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir, NULL,
+ &sc_prefetch_fops);
return 0;
}
late_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)
local_irq_restore(flags);
}
-void local_flush_tlb_mm(struct mm_struct *mm)
-{
- int cpu = smp_processor_id();
-
- if (cpu_context(cpu, mm) != 0) {
-#ifdef DEBUG_TLB
- printk("[tlbmm<%lu>]", (unsigned long)cpu_context(cpu, mm));
-#endif
- drop_mmu_context(mm, cpu);
- }
-}
-
void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
@@ -117,7 +105,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
}
write_c0_entryhi(oldpid);
} else {
- drop_mmu_context(mm, cpu);
+ drop_mmu_context(mm);
}
local_irq_restore(flags);
}
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)
}
EXPORT_SYMBOL(local_flush_tlb_all);
-/* All entries common to a mm share an asid. To effectively flush
- these entries, we just bump the asid. */
-void local_flush_tlb_mm(struct mm_struct *mm)
-{
- int cpu;
-
- preempt_disable();
-
- cpu = smp_processor_id();
-
- if (cpu_context(cpu, mm) != 0) {
- drop_mmu_context(mm, cpu);
- }
-
- preempt_enable();
-}
-
void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
@@ -137,14 +120,23 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
if (size <= (current_cpu_data.tlbsizeftlbsets ?
current_cpu_data.tlbsize / 8 :
current_cpu_data.tlbsize / 2)) {
- int oldpid = read_c0_entryhi();
+ unsigned long old_entryhi, uninitialized_var(old_mmid);
int newpid = cpu_asid(cpu, mm);
+ old_entryhi = read_c0_entryhi();
+ if (cpu_has_mmid) {
+ old_mmid = read_c0_memorymapid();
+ write_c0_memorymapid(newpid);
+ }
+
htw_stop();
while (start < end) {
int idx;
- write_c0_entryhi(start | newpid);
+ if (cpu_has_mmid)
+ write_c0_entryhi(start);
+ else
+ write_c0_entryhi(start | newpid);
start += (PAGE_SIZE << 1);
mtc0_tlbw_hazard();
tlb_probe();
@@ -160,10 +152,12 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
tlb_write_indexed();
}
tlbw_use_hazard();
- write_c0_entryhi(oldpid);
+ write_c0_entryhi(old_entryhi);
+ if (cpu_has_mmid)
+ write_c0_memorymapid(old_mmid);
htw_start();
} else {
- drop_mmu_context(mm, cpu);
+ drop_mmu_context(mm);
}
flush_micro_tlb();
local_irq_restore(flags);
@@ -220,15 +214,21 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
int cpu = smp_processor_id();
if (cpu_context(cpu, vma->vm_mm) != 0) {
- unsigned long flags;
- int oldpid, newpid, idx;
+ unsigned long uninitialized_var(old_mmid);
+ unsigned long flags, old_entryhi;
+ int idx;
- newpid = cpu_asid(cpu, vma->vm_mm);
page &= (PAGE_MASK << 1);
local_irq_save(flags);
- oldpid = read_c0_entryhi();
+ old_entryhi = read_c0_entryhi();
htw_stop();
- write_c0_entryhi(page | newpid);
+ if (cpu_has_mmid) {
+ old_mmid = read_c0_memorymapid();
+ write_c0_entryhi(page);
+ write_c0_memorymapid(cpu_asid(cpu, vma->vm_mm));
+ } else {
+ write_c0_entryhi(page | cpu_asid(cpu, vma->vm_mm));
+ }
mtc0_tlbw_hazard();
tlb_probe();
tlb_probe_hazard();
@@ -244,7 +244,9 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
tlbw_use_hazard();
finish:
- write_c0_entryhi(oldpid);
+ write_c0_entryhi(old_entryhi);
+ if (cpu_has_mmid)
+ write_c0_memorymapid(old_mmid);
htw_start();
flush_micro_tlb_vm(vma);
local_irq_restore(flags);
@@ -307,9 +309,13 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
local_irq_save(flags);
htw_stop();
- pid = read_c0_entryhi() & cpu_asid_mask(&current_cpu_data);
address &= (PAGE_MASK << 1);
- write_c0_entryhi(address | pid);
+ if (cpu_has_mmid) {
+ write_c0_entryhi(address);
+ } else {
+ pid = read_c0_entryhi() & cpu_asid_mask(&current_cpu_data);
+ write_c0_entryhi(address | pid);
+ }
pgdp = pgd_offset(vma->vm_mm, address);
mtc0_tlbw_hazard();
tlb_probe();
@@ -375,12 +381,17 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
#ifdef CONFIG_XPA
panic("Broken for XPA kernels");
#else
+ unsigned int uninitialized_var(old_mmid);
unsigned long flags;
unsigned long wired;
unsigned long old_pagemask;
unsigned long old_ctx;
local_irq_save(flags);
+ if (cpu_has_mmid) {
+ old_mmid = read_c0_memorymapid();
+ write_c0_memorymapid(MMID_KERNEL_WIRED);
+ }
/* Save old context and create impossible VPN2 value */
old_ctx = read_c0_entryhi();
htw_stop();
@@ -398,6 +409,8 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
tlbw_use_hazard();
write_c0_entryhi(old_ctx);
+ if (cpu_has_mmid)
+ write_c0_memorymapid(old_mmid);
tlbw_use_hazard(); /* What is the hazard here? */
htw_start();
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)
local_irq_restore(flags);
}
-void local_flush_tlb_mm(struct mm_struct *mm)
-{
- int cpu = smp_processor_id();
-
- if (cpu_context(cpu, mm) != 0)
- drop_mmu_context(mm, cpu);
-}
-
void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
@@ -75,7 +67,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
local_irq_save(flags);
if (size > TFP_TLB_SIZE / 2) {
- drop_mmu_context(mm, cpu);
+ drop_mmu_context(mm);
goto out_restore;
}
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
#
# These are still pretty much in the old state, watch, go blind.
#
+obj-$(CONFIG_ATH79) += fixup-ath79.o
obj-$(CONFIG_LASAT) += pci-lasat.o
obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
obj-$(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 @@
+/*
+ * Copyright (C) 2018 John Crispin <john@phrozen.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/pci.h>
+//#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return of_irq_parse_and_map_pci(dev, slot, pin);
+}
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,
int where, int size, u32 * value)
{
struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
- bridge_t *bridge = bc->base;
+ struct bridge_regs *bridge = bc->base;
int slot = PCI_SLOT(devfn);
int fn = PCI_FUNC(devfn);
volatile void *addr;
@@ -56,11 +56,11 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_DEVICE_NOT_FOUND;
/*
- * IOC3 is fucking fucked beyond belief ... Don't even give the
+ * IOC3 is broken beyond belief ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
- goto oh_my_gawd;
+ goto is_ioc3;
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
@@ -73,21 +73,16 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-oh_my_gawd:
+is_ioc3:
/*
- * IOC3 is fucking fucked beyond belief ... Don't even give the
- * generic PCI code a chance to look at the wrong register.
+ * IOC3 special handling
*/
if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
*value = emulate_ioc3_cfg(where, size);
return PCIBIOS_SUCCESSFUL;
}
- /*
- * IOC3 is fucking fucked beyond belief ... Don't try to access
- * anything but 32-bit words ...
- */
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
if (get_dbe(cf, (u32 *) addr))
@@ -104,7 +99,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 * value)
{
struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
- bridge_t *bridge = bc->base;
+ struct bridge_regs *bridge = bc->base;
int busno = bus->number;
int slot = PCI_SLOT(devfn);
int fn = PCI_FUNC(devfn);
@@ -112,19 +107,19 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
u32 cf, shift, mask;
int res;
- bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+ bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
if (get_dbe(cf, (u32 *) addr))
return PCIBIOS_DEVICE_NOT_FOUND;
/*
- * IOC3 is fucking fucked beyond belief ... Don't even give the
+ * IOC3 is broken beyond belief ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
- goto oh_my_gawd;
+ goto is_ioc3;
- bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+ bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
if (size == 1)
@@ -136,22 +131,17 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-oh_my_gawd:
+is_ioc3:
/*
- * IOC3 is fucking fucked beyond belief ... Don't even give the
- * generic PCI code a chance to look at the wrong register.
+ * IOC3 special handling
*/
if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
*value = emulate_ioc3_cfg(where, size);
return PCIBIOS_SUCCESSFUL;
}
- /*
- * IOC3 is fucking fucked beyond belief ... Don't try to access
- * anything but 32-bit words ...
- */
- bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+ bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
if (get_dbe(cf, (u32 *) addr))
@@ -177,7 +167,7 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value)
{
struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
- bridge_t *bridge = bc->base;
+ struct bridge_regs *bridge = bc->base;
int slot = PCI_SLOT(devfn);
int fn = PCI_FUNC(devfn);
volatile void *addr;
@@ -189,11 +179,11 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_DEVICE_NOT_FOUND;
/*
- * IOC3 is fucking fucked beyond belief ... Don't even give the
+ * IOC3 is broken beyond belief ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
- goto oh_my_gawd;
+ goto is_ioc3;
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
@@ -210,19 +200,14 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_SUCCESSFUL;
-oh_my_gawd:
+is_ioc3:
/*
- * IOC3 is fucking fucked beyond belief ... Don't even give the
- * generic PCI code a chance to touch the wrong register.
+ * IOC3 special handling
*/
if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
return PCIBIOS_SUCCESSFUL;
- /*
- * IOC3 is fucking fucked beyond belief ... Don't try to access
- * anything but 32-bit words ...
- */
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
if (get_dbe(cf, (u32 *) addr))
@@ -243,7 +228,7 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value)
{
struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
- bridge_t *bridge = bc->base;
+ struct bridge_regs *bridge = bc->base;
int slot = PCI_SLOT(devfn);
int fn = PCI_FUNC(devfn);
int busno = bus->number;
@@ -251,17 +236,17 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
u32 cf, shift, mask, smask;
int res;
- bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+ bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
if (get_dbe(cf, (u32 *) addr))
return PCIBIOS_DEVICE_NOT_FOUND;
/*
- * IOC3 is fucking fucked beyond belief ... Don't even give the
+ * IOC3 is broken beyond belief ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
- goto oh_my_gawd;
+ goto is_ioc3;
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
@@ -278,19 +263,14 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_SUCCESSFUL;
-oh_my_gawd:
+is_ioc3:
/*
- * IOC3 is fucking fucked beyond belief ... Don't even give the
- * generic PCI code a chance to touch the wrong register.
+ * IOC3 special handling
*/
if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
return PCIBIOS_SUCCESSFUL;
- /*
- * IOC3 is fucking fucked beyond belief ... Don't try to access
- * anything but 32-bit words ...
- */
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
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 @@
#define MAX_PCI_BUSSES 40
/*
- * Max #PCI devices (like scsi controllers) we handle on a bus.
- */
-#define MAX_DEVICES_PER_PCIBUS 8
-
-/*
* XXX: No kmalloc available when we do our crosstalk scan,
* we should try to move it later in the boot process.
*/
static struct bridge_controller bridges[MAX_PCI_BUSSES];
-/*
- * Translate from irq to software PCI bus number and PCI slot.
- */
-struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
-int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
-
extern struct pci_ops bridge_pci_ops;
int 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)
unsigned long offset = NODE_OFFSET(nasid);
struct bridge_controller *bc;
static int num_bridges = 0;
- bridge_t *bridge;
int slot;
pci_set_flags(PCI_PROBE_ONLY);
@@ -78,7 +66,6 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
bc->io.end = ~0UL;
bc->io.flags = IORESOURCE_IO;
- bc->irq_cpu = smp_processor_id();
bc->widget_id = widget_id;
bc->nasid = nasid;
@@ -87,45 +74,43 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
/*
* point to this bridge
*/
- bridge = (bridge_t *) RAW_NODE_SWIN_BASE(nasid, widget_id);
+ bc->base = (struct bridge_regs *)RAW_NODE_SWIN_BASE(nasid, widget_id);
/*
* Clear all pending interrupts.
*/
- bridge->b_int_rst_stat = BRIDGE_IRR_ALL_CLR;
+ bridge_write(bc, b_int_rst_stat, BRIDGE_IRR_ALL_CLR);
/*
* Until otherwise set up, assume all interrupts are from slot 0
*/
- bridge->b_int_device = 0x0;
+ bridge_write(bc, b_int_device, 0x0);
/*
* swap pio's to pci mem and io space (big windows)
*/
- bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP |
- BRIDGE_CTRL_MEM_SWAP;
+ bridge_set(bc, b_wid_control, BRIDGE_CTRL_IO_SWAP |
+ BRIDGE_CTRL_MEM_SWAP);
#ifdef CONFIG_PAGE_SIZE_4KB
- bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE;
+ bridge_clr(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
#else /* 16kB or larger */
- bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE;
+ bridge_set(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
#endif
/*
* Hmm... IRIX sets additional bits in the address which
* are documented as reserved in the bridge docs.
*/
- bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
- bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/
- bridge->b_dir_map = (masterwid << 20); /* DMA */
- bridge->b_int_enable = 0;
+ bridge_write(bc, b_wid_int_upper, 0x8000 | (masterwid << 16));
+ bridge_write(bc, b_wid_int_lower, 0x01800090); /* PI_INT_PEND_MOD off*/
+ bridge_write(bc, b_dir_map, (masterwid << 20)); /* DMA */
+ bridge_write(bc, b_int_enable, 0);
for (slot = 0; slot < 8; slot ++) {
- bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
+ bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR);
bc->pci_int[slot] = -1;
}
- bridge->b_wid_tflush; /* wait until Bridge PIO complete */
-
- bc->base = bridge;
+ bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */
register_pci_controller(&bc->pc);
@@ -168,16 +153,12 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
irq = bc->pci_int[slot];
if (irq == -1) {
- irq = request_bridge_irq(bc);
+ irq = request_bridge_irq(bc, slot);
if (irq < 0)
return irq;
bc->pci_int[slot] = irq;
}
-
- irq_to_bridge[irq] = bc;
- irq_to_slot[irq] = slot;
-
dev->irq = irq;
return 0;
@@ -206,7 +187,7 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
static inline void pci_disable_swapping(struct pci_dev *dev)
{
struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
- bridge_t *bridge = bc->base;
+ struct bridge_regs *bridge = bc->base;
int slot = PCI_SLOT(dev->devfn);
/* 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 = {
static int bootrom_setup(void)
{
- if (!debugfs_create_file("bootrom", 0444,
- NULL, NULL, &bootrom_file_ops)) {
- pr_err("Failed to create bootrom debugfs file\n");
-
- return -EINVAL;
- }
-
+ debugfs_create_file("bootrom", 0444, NULL, NULL, &bootrom_file_ops);
return 0;
}
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 @@
# Makefile for the IP27 specific kernel interface routines under Linux.
#
-obj-y := ip27-berr.o ip27-irq.o ip27-irqno.o ip27-init.o ip27-klconfig.o \
+obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o \
ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \
ip27-hubio.o ip27-xtalk.o
obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o
-obj-$(CONFIG_PCI) += ip27-irq-pci.o
obj-$(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,
* after we write it.
*/
IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr);
- (void) HUB_L(IIO_ITTE_GET(nasid, i));
+ __raw_readq(IIO_ITTE_GET(nasid, i));
return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE);
}
@@ -135,7 +135,7 @@ static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
**/
static void hub_set_piomode(nasid_t nasid)
{
- hubreg_t ii_iowa;
+ u64 ii_iowa;
hubii_wcr_t ii_wcr;
unsigned i;
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);
extern void pcibr_setup(cnodeid_t);
-extern void xtalk_probe_node(cnodeid_t nid);
-
static void per_hub_init(cnodeid_t cnode)
{
struct hub_data *hub = hub_data(cnode);
nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
- int i;
cpumask_set_cpu(smp_processor_id(), &hub->h_cpus);
@@ -71,7 +68,6 @@ static void per_hub_init(cnodeid_t cnode)
REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
hub_rtc_init(cnode);
- xtalk_probe_node(cnode);
#ifdef CONFIG_REPLICATE_EXHANDLERS
/*
@@ -90,24 +86,6 @@ static void per_hub_init(cnodeid_t cnode)
__flush_cache_all();
}
#endif
-
- /*
- * Some interrupts are reserved by hardware or by software convention.
- * Mark these as reserved right away so they won't be used accidentally
- * later.
- */
- for (i = 0; i <= BASE_PCI_IRQ; i++) {
- __set_bit(i, hub->irq_alloc_mask);
- LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
- }
-
- __set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
- LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
-
- for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
- __set_bit(i, hub->irq_alloc_mask);
- LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
- }
}
void per_cpu_init(void)
@@ -116,8 +94,6 @@ void per_cpu_init(void)
int slice = LOCAL_HUB_L(PI_CPU_NUM);
cnodeid_t cnode = get_compact_nodeid();
struct hub_data *hub = hub_data(cnode);
- struct slice_data *si = hub->slice + slice;
- int i;
if (test_and_set_bit(slice, &hub->slice_map))
return;
@@ -126,22 +102,14 @@ void per_cpu_init(void)
per_hub_init(cnode);
- for (i = 0; i < LEVELS_PER_SLICE; i++)
- si->level_to_irq[i] = -1;
-
- /*
- * We use this so we can find the local hub's data as fast as only
- * possible.
- */
- cpu_data[cpu].data = si;
-
cpu_time_init();
install_ipi();
/* Install our NMI handler if symmon hasn't installed one. */
install_cpu_nmi_handler(cputoslice(cpu));
- set_c0_status(SRB_DEV0 | SRB_DEV1);
+ enable_percpu_irq(IP27_HUB_PEND0_IRQ, IRQ_TYPE_NONE);
+ enable_percpu_irq(IP27_HUB_PEND1_IRQ, IRQ_TYPE_NONE);
}
/*
@@ -177,7 +145,7 @@ extern void ip27_reboot_setup(void);
void __init plat_mem_setup(void)
{
- hubreg_t p, e, n_mode;
+ u64 p, e, n_mode;
nasid_t nid;
ip27_reboot_setup();
@@ -215,7 +183,6 @@ void __init plat_mem_setup(void)
#endif
ioc3_eth_init();
- per_cpu_init();
set_io_port_base(IO_BASE);
}
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 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
- *
- * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- * Copyright (C) 1999 - 2001 Kanoj Sarcar
- */
-
-#undef DEBUG
-
-#include <linux/irq.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/smp.h>
-#include <linux/random.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-
-#include <asm/processor.h>
-#include <asm/pci/bridge.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/agent.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/hub.h>
-#include <asm/sn/intr.h>
-
-/*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the appropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
-
-extern struct bridge_controller *irq_to_bridge[];
-extern int irq_to_slot[];
-
-/*
- * use these macros to get the encoded nasid and widget id
- * from the irq value
- */
-#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)]
-#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i]
-
-static inline int alloc_level(int cpu, int irq)
-{
- struct hub_data *hub = hub_data(cpu_to_node(cpu));
- struct slice_data *si = cpu_data[cpu].data;
- int level;
-
- level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
- if (level >= LEVELS_PER_SLICE)
- panic("Cpu %d flooded with devices", cpu);
-
- __set_bit(level, hub->irq_alloc_mask);
- si->level_to_irq[level] = irq;
-
- return level;
-}
-
-static inline int find_level(cpuid_t *cpunum, int irq)
-{
- int cpu, i;
-
- for_each_online_cpu(cpu) {
- struct slice_data *si = cpu_data[cpu].data;
-
- for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
- if (si->level_to_irq[i] == irq) {
- *cpunum = cpu;
-
- return i;
- }
- }
-
- panic("Could not identify cpu/level for irq %d", irq);
-}
-
-static int intr_connect_level(int cpu, int bit)
-{
- nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
- struct slice_data *si = cpu_data[cpu].data;
-
- set_bit(bit, si->irq_enable_mask);
-
- if (!cputoslice(cpu)) {
- REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
- REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
- } else {
- REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
- REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
- }
-
- return 0;
-}
-
-static int intr_disconnect_level(int cpu, int bit)
-{
- nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
- struct slice_data *si = cpu_data[cpu].data;
-
- clear_bit(bit, si->irq_enable_mask);
-
- if (!cputoslice(cpu)) {
- REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
- REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
- } else {
- REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
- REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
- }
-
- return 0;
-}
-
-/* Startup one of the (PCI ...) IRQs routes over a bridge. */
-static unsigned int startup_bridge_irq(struct irq_data *d)
-{
- struct bridge_controller *bc;
- bridgereg_t device;
- bridge_t *bridge;
- int pin, swlevel;
- cpuid_t cpu;
-
- pin = SLOT_FROM_PCI_IRQ(d->irq);
- bc = IRQ_TO_BRIDGE(d->irq);
- bridge = bc->base;
-
- pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin);
- /*
- * "map" irq to a swlevel greater than 6 since the first 6 bits
- * of INT_PEND0 are taken
- */
- swlevel = find_level(&cpu, d->irq);
- bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
- bridge->b_int_enable |= (1 << pin);
- bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */
-
- /*
- * Enable sending of an interrupt clear packt to the hub on a high to
- * low transition of the interrupt pin.
- *
- * IRIX sets additional bits in the address which are documented as
- * reserved in the bridge docs.
- */
- bridge->b_int_mode |= (1UL << pin);
-
- /*
- * We assume the bridge to have a 1:1 mapping between devices
- * (slots) and intr pins.
- */
- device = bridge->b_int_device;
- device &= ~(7 << (pin*3));
- device |= (pin << (pin*3));
- bridge->b_int_device = device;
-
- bridge->b_wid_tflush;
-
- intr_connect_level(cpu, swlevel);
-
- return 0; /* Never anything pending. */
-}
-
-/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */
-static void shutdown_bridge_irq(struct irq_data *d)
-{
- struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
- bridge_t *bridge = bc->base;
- int pin, swlevel;
- cpuid_t cpu;
-
- pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
- pin = SLOT_FROM_PCI_IRQ(d->irq);
-
- /*
- * map irq to a swlevel greater than 6 since the first 6 bits
- * of INT_PEND0 are taken
- */
- swlevel = find_level(&cpu, d->irq);
- intr_disconnect_level(cpu, swlevel);
-
- bridge->b_int_enable &= ~(1 << pin);
- bridge->b_wid_tflush;
-}
-
-static inline void enable_bridge_irq(struct irq_data *d)
-{
- cpuid_t cpu;
- int swlevel;
-
- swlevel = find_level(&cpu, d->irq); /* Criminal offence */
- intr_connect_level(cpu, swlevel);
-}
-
-static inline void disable_bridge_irq(struct irq_data *d)
-{
- cpuid_t cpu;
- int swlevel;
-
- swlevel = find_level(&cpu, d->irq); /* Criminal offence */
- intr_disconnect_level(cpu, swlevel);
-}
-
-static struct irq_chip bridge_irq_type = {
- .name = "bridge",
- .irq_startup = startup_bridge_irq,
- .irq_shutdown = shutdown_bridge_irq,
- .irq_mask = disable_bridge_irq,
- .irq_unmask = enable_bridge_irq,
-};
-
-void register_bridge_irq(unsigned int irq)
-{
- irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
-}
-
-int request_bridge_irq(struct bridge_controller *bc)
-{
- int irq = allocate_irqno();
- int swlevel, cpu;
- nasid_t nasid;
-
- if (irq < 0)
- return irq;
-
- /*
- * "map" irq to a swlevel greater than 6 since the first 6 bits
- * of INT_PEND0 are taken
- */
- cpu = bc->irq_cpu;
- swlevel = alloc_level(cpu, irq);
- if (unlikely(swlevel < 0)) {
- free_irqno(irq);
-
- return -EAGAIN;
- }
-
- /* Make sure it's not already pending when we connect it. */
- nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
- REMOTE_HUB_CLR_INTR(nasid, swlevel);
-
- intr_connect_level(cpu, swlevel);
-
- register_bridge_irq(irq);
-
- return irq;
-}
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 @@
* Copyright (C) 1999 - 2001 Kanoj Sarcar
*/
-#undef DEBUG
-
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/smp.h>
-#include <linux/random.h>
#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
#include <linux/bitops.h>
-#include <asm/bootinfo.h>
#include <asm/io.h>
-#include <asm/mipsregs.h>
-
-#include <asm/processor.h>
+#include <asm/irq_cpu.h>
+#include <asm/pci/bridge.h>
#include <asm/sn/addrs.h>
#include <asm/sn/agent.h>
#include <asm/sn/arch.h>
#include <asm/sn/hub.h>
#include <asm/sn/intr.h>
-/*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the appropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
+struct hub_irq_data {
+ struct bridge_controller *bc;
+ u64 *irq_mask[2];
+ cpuid_t cpu;
+ int bit;
+ int pin;
+};
-extern asmlinkage void ip27_irq(void);
+static DECLARE_BITMAP(hub_irq_map, IP27_HUB_IRQ_COUNT);
-/*
- * Find first bit set
- */
-static int ms1bit(unsigned long x)
+static DEFINE_PER_CPU(unsigned long [2], irq_enable_mask);
+
+static inline int alloc_level(void)
+{
+ int level;
+
+again:
+ level = find_first_zero_bit(hub_irq_map, IP27_HUB_IRQ_COUNT);
+ if (level >= IP27_HUB_IRQ_COUNT)
+ return -ENOSPC;
+
+ if (test_and_set_bit(level, hub_irq_map))
+ goto again;
+
+ return level;
+}
+
+static void enable_hub_irq(struct irq_data *d)
+{
+ struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
+ unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu);
+
+ set_bit(hd->bit, mask);
+ __raw_writeq(mask[0], hd->irq_mask[0]);
+ __raw_writeq(mask[1], hd->irq_mask[1]);
+}
+
+static void disable_hub_irq(struct irq_data *d)
+{
+ struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
+ unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu);
+
+ clear_bit(hd->bit, mask);
+ __raw_writeq(mask[0], hd->irq_mask[0]);
+ __raw_writeq(mask[1], hd->irq_mask[1]);
+}
+
+static unsigned int startup_bridge_irq(struct irq_data *d)
+{
+ struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
+ struct bridge_controller *bc;
+ nasid_t nasid;
+ u32 device;
+ int pin;
+
+ if (!hd)
+ return -EINVAL;
+
+ pin = hd->pin;
+ bc = hd->bc;
+
+ nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(hd->cpu));
+ bridge_write(bc, b_int_addr[pin].addr,
+ (0x20000 | hd->bit | (nasid << 8)));
+ bridge_set(bc, b_int_enable, (1 << pin));
+ bridge_set(bc, b_int_enable, 0x7ffffe00); /* more stuff in int_enable */
+
+ /*
+ * Enable sending of an interrupt clear packt to the hub on a high to
+ * low transition of the interrupt pin.
+ *
+ * IRIX sets additional bits in the address which are documented as
+ * reserved in the bridge docs.
+ */
+ bridge_set(bc, b_int_mode, (1UL << pin));
+
+ /*
+ * We assume the bridge to have a 1:1 mapping between devices
+ * (slots) and intr pins.
+ */
+ device = bridge_read(bc, b_int_device);
+ device &= ~(7 << (pin*3));
+ device |= (pin << (pin*3));
+ bridge_write(bc, b_int_device, device);
+
+ bridge_read(bc, b_wid_tflush);
+
+ enable_hub_irq(d);
+
+ return 0; /* Never anything pending. */
+}
+
+static void shutdown_bridge_irq(struct irq_data *d)
+{
+ struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
+ struct bridge_controller *bc;
+ int pin = hd->pin;
+
+ if (!hd)
+ return;
+
+ disable_hub_irq(d);
+
+ bc = hd->bc;
+ bridge_clr(bc, b_int_enable, (1 << pin));
+ bridge_read(bc, b_wid_tflush);
+}
+
+static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask)
+{
+ nasid_t nasid;
+ int cpu;
+
+ cpu = cpumask_first_and(mask, cpu_online_mask);
+ nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+ hd->cpu = cpu;
+ if (!cputoslice(cpu)) {
+ hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_A);
+ hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_A);
+ } else {
+ hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_B);
+ hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_B);
+ }
+
+ /* Make sure it's not already pending when we connect it. */
+ REMOTE_HUB_CLR_INTR(nasid, hd->bit);
+}
+
+static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask,
+ bool force)
+{
+ struct hub_irq_data *hd = irq_data_get_irq_chip_data(d);
+
+ if (!hd)
+ return -EINVAL;
+
+ if (irqd_is_started(d))
+ disable_hub_irq(d);
+
+ setup_hub_mask(hd, mask);
+
+ if (irqd_is_started(d))
+ startup_bridge_irq(d);
+
+ irq_data_update_effective_affinity(d, cpumask_of(hd->cpu));
+
+ return 0;
+}
+
+static struct irq_chip hub_irq_type = {
+ .name = "HUB",
+ .irq_startup = startup_bridge_irq,
+ .irq_shutdown = shutdown_bridge_irq,
+ .irq_mask = disable_hub_irq,
+ .irq_unmask = enable_hub_irq,
+ .irq_set_affinity = set_affinity_hub_irq,
+};
+
+int request_bridge_irq(struct bridge_controller *bc, int pin)
{
- int b = 0, s;
+ struct hub_irq_data *hd;
+ struct hub_data *hub;
+ struct irq_desc *desc;
+ int swlevel;
+ int irq;
+
+ hd = kzalloc(sizeof(*hd), GFP_KERNEL);
+ if (!hd)
+ return -ENOMEM;
+
+ swlevel = alloc_level();
+ if (unlikely(swlevel < 0)) {
+ kfree(hd);
+ return -EAGAIN;
+ }
+ irq = swlevel + IP27_HUB_IRQ_BASE;
+
+ hd->bc = bc;
+ hd->bit = swlevel;
+ hd->pin = pin;
+ irq_set_chip_data(irq, hd);
+
+ /* use CPU connected to nearest hub */
+ hub = hub_data(NASID_TO_COMPACT_NODEID(bc->nasid));
+ setup_hub_mask(hd, &hub->h_cpus);
- s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s;
- s = 8; if (x >> 8 == 0) s = 0; b += s; x >>= s;
- s = 4; if (x >> 4 == 0) s = 0; b += s; x >>= s;
- s = 2; if (x >> 2 == 0) s = 0; b += s; x >>= s;
- s = 1; if (x >> 1 == 0) s = 0; b += s;
+ desc = irq_to_desc(irq);
+ desc->irq_common_data.node = bc->nasid;
+ cpumask_copy(desc->irq_common_data.affinity, &hub->h_cpus);
- return b;
+ return irq;
+}
+
+void ip27_hub_irq_init(void)
+{
+ int i;
+
+ for (i = IP27_HUB_IRQ_BASE;
+ i < (IP27_HUB_IRQ_BASE + IP27_HUB_IRQ_COUNT); i++)
+ irq_set_chip_and_handler(i, &hub_irq_type, handle_level_irq);
+
+ /*
+ * Some interrupts are reserved by hardware or by software convention.
+ * Mark these as reserved right away so they won't be used accidentally
+ * later.
+ */
+ for (i = 0; i <= BASE_PCI_IRQ; i++)
+ set_bit(i, hub_irq_map);
+
+ set_bit(IP_PEND0_6_63, hub_irq_map);
+
+ for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++)
+ set_bit(i, hub_irq_map);
}
/*
@@ -82,23 +249,19 @@ static int ms1bit(unsigned long x)
* Kanoj 05.13.00
*/
-static void ip27_do_irq_mask0(void)
+static void ip27_do_irq_mask0(struct irq_desc *desc)
{
- int irq, swlevel;
- hubreg_t pend0, mask0;
cpuid_t cpu = smp_processor_id();
- int pi_int_mask0 =
- (cputoslice(cpu) == 0) ? PI_INT_MASK0_A : PI_INT_MASK0_B;
+ unsigned long *mask = per_cpu(irq_enable_mask, cpu);
+ u64 pend0;
/* copied from Irix intpend0() */
pend0 = LOCAL_HUB_L(PI_INT_PEND0);
- mask0 = LOCAL_HUB_L(pi_int_mask0);
- pend0 &= mask0; /* Pick intrs we should look at */
+ pend0 &= mask[0]; /* Pick intrs we should look at */
if (!pend0)
return;
- swlevel = ms1bit(pend0);
#ifdef CONFIG_SMP
if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) {
LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
@@ -108,106 +271,66 @@ static void ip27_do_irq_mask0(void)
scheduler_ipi();
} else if (pend0 & (1UL << CPU_CALL_A_IRQ)) {
LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
- irq_enter();
generic_smp_call_function_interrupt();
- irq_exit();
} else if (pend0 & (1UL << CPU_CALL_B_IRQ)) {
LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
- irq_enter();
generic_smp_call_function_interrupt();
- irq_exit();
} else
#endif
- {
- /* "map" swlevel to irq */
- struct slice_data *si = cpu_data[cpu].data;
-
- irq = si->level_to_irq[swlevel];
- do_IRQ(irq);
- }
+ generic_handle_irq(__ffs(pend0) + IP27_HUB_IRQ_BASE);
LOCAL_HUB_L(PI_INT_PEND0);
}
-static void ip27_do_irq_mask1(void)
+static void ip27_do_irq_mask1(struct irq_desc *desc)
{
- int irq, swlevel;
- hubreg_t pend1, mask1;
cpuid_t cpu = smp_processor_id();
- int pi_int_mask1 = (cputoslice(cpu) == 0) ? PI_INT_MASK1_A : PI_INT_MASK1_B;
- struct slice_data *si = cpu_data[cpu].data;
+ unsigned long *mask = per_cpu(irq_enable_mask, cpu);
+ u64 pend1;
/* copied from Irix intpend0() */
pend1 = LOCAL_HUB_L(PI_INT_PEND1);
- mask1 = LOCAL_HUB_L(pi_int_mask1);
- pend1 &= mask1; /* Pick intrs we should look at */
+ pend1 &= mask[1]; /* Pick intrs we should look at */
if (!pend1)
return;
- swlevel = ms1bit(pend1);
- /* "map" swlevel to irq */
- irq = si->level_to_irq[swlevel];
- LOCAL_HUB_CLR_INTR(swlevel);
- do_IRQ(irq);
+ generic_handle_irq(__ffs(pend1) + IP27_HUB_IRQ_BASE + 64);
LOCAL_HUB_L(PI_INT_PEND1);
}
-static void ip27_prof_timer(void)
-{
- panic("CPU %d got a profiling interrupt", smp_processor_id());
-}
-
-static void ip27_hub_error(void)
-{
- panic("CPU %d got a hub error interrupt", smp_processor_id());
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
- unsigned long pending = read_c0_cause() & read_c0_status();
- extern unsigned int rt_timer_irq;
-
- if (pending & CAUSEF_IP4)
- do_IRQ(rt_timer_irq);
- else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */
- ip27_do_irq_mask0();
- else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */
- ip27_do_irq_mask1();
- else if (pending & CAUSEF_IP5)
- ip27_prof_timer();
- else if (pending & CAUSEF_IP6)
- ip27_hub_error();
-}
-
-void __init arch_init_irq(void)
-{
-}
-
void install_ipi(void)
{
- int slice = LOCAL_HUB_L(PI_CPU_NUM);
int cpu = smp_processor_id();
- struct slice_data *si = cpu_data[cpu].data;
- struct hub_data *hub = hub_data(cpu_to_node(cpu));
+ unsigned long *mask = per_cpu(irq_enable_mask, cpu);
+ int slice = LOCAL_HUB_L(PI_CPU_NUM);
int resched, call;
resched = CPU_RESCHED_A_IRQ + slice;
- __set_bit(resched, hub->irq_alloc_mask);
- __set_bit(resched, si->irq_enable_mask);
+ set_bit(resched, mask);
LOCAL_HUB_CLR_INTR(resched);
call = CPU_CALL_A_IRQ + slice;
- __set_bit(call, hub->irq_alloc_mask);
- __set_bit(call, si->irq_enable_mask);
+ set_bit(call, mask);
LOCAL_HUB_CLR_INTR(call);
if (slice == 0) {
- LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]);
- LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]);
+ LOCAL_HUB_S(PI_INT_MASK0_A, mask[0]);
+ LOCAL_HUB_S(PI_INT_MASK1_A, mask[1]);
} else {
- LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]);
- LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]);
+ LOCAL_HUB_S(PI_INT_MASK0_B, mask[0]);
+ LOCAL_HUB_S(PI_INT_MASK1_B, mask[1]);
}
}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+ ip27_hub_irq_init();
+
+ irq_set_percpu_devid(IP27_HUB_PEND0_IRQ);
+ irq_set_chained_handler(IP27_HUB_PEND0_IRQ, ip27_do_irq_mask0);
+ irq_set_percpu_devid(IP27_HUB_PEND1_IRQ);
+ irq_set_chained_handler(IP27_HUB_PEND1_IRQ, ip27_do_irq_mask1);
+}
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 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/types.h>
-
-#include <asm/barrier.h>
-
-static DECLARE_BITMAP(irq_map, NR_IRQS);
-
-int allocate_irqno(void)
-{
- int irq;
-
-again:
- irq = find_first_zero_bit(irq_map, NR_IRQS);
-
- if (irq >= NR_IRQS)
- return -ENOSPC;
-
- if (test_and_set_bit(irq, irq_map))
- goto again;
-
- return irq;
-}
-
-/*
- * Allocate the 16 legacy interrupts for i8259 devices. This happens early
- * in the kernel initialization so treating allocation failure as BUG() is
- * ok.
- */
-void __init alloc_legacy_irqno(void)
-{
- int i;
-
- for (i = 0; i <= 16; i++)
- BUG_ON(test_and_set_bit(i, irq_map));
-}
-
-void free_irqno(unsigned int irq)
-{
- smp_mb__before_atomic();
- clear_bit(irq, irq_map);
- smp_mb__after_atomic();
-}
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)
return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE;
}
-static hubreg_t get_region(cnodeid_t cnode)
+static u64 get_region(cnodeid_t cnode)
{
if (fine_mode)
return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
@@ -52,9 +52,9 @@ static hubreg_t get_region(cnodeid_t cnode)
return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
}
-static hubreg_t region_mask;
+static u64 region_mask;
-static void gen_region_mask(hubreg_t *region_mask)
+static void gen_region_mask(u64 *region_mask)
{
cnodeid_t cnode;
@@ -154,11 +154,11 @@ static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
}
if (router_a == NULL) {
- printk("node_distance: router_a NULL\n");
+ pr_info("node_distance: router_a NULL\n");
return -1;
}
if (router_b == NULL) {
- printk("node_distance: router_b NULL\n");
+ pr_info("node_distance: router_b NULL\n");
return -1;
}
@@ -203,17 +203,17 @@ static void __init dump_topology(void)
klrou_t *router;
cnodeid_t row, col;
- printk("************** Topology ********************\n");
+ pr_info("************** Topology ********************\n");
- printk(" ");
+ pr_info(" ");
for_each_online_node(col)
- printk("%02d ", col);
- printk("\n");
+ pr_cont("%02d ", col);
+ pr_cont("\n");
for_each_online_node(row) {
- printk("%02d ", row);
+ pr_info("%02d ", row);
for_each_online_node(col)
- printk("%2d ", node_distance(row, col));
- printk("\n");
+ pr_cont("%2d ", node_distance(row, col));
+ pr_cont("\n");
}
for_each_online_node(cnode) {
@@ -230,7 +230,7 @@ static void __init dump_topology(void)
do {
if (brd->brd_flags & DUPLICATE_BOARD)
continue;
- printk("Router %d:", router_num);
+ pr_cont("Router %d:", router_num);
router_num++;
router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
@@ -244,11 +244,11 @@ static void __init dump_topology(void)
router->rou_port[port].port_offset);
if (dest_brd->brd_type == KLTYPE_IP27)
- printk(" %d", dest_brd->brd_nasid);
+ pr_cont(" %d", dest_brd->brd_nasid);
if (dest_brd->brd_type == KLTYPE_ROUTER)
- printk(" r");
+ pr_cont(" r");
}
- printk("\n");
+ pr_cont("\n");
} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
}
@@ -373,7 +373,7 @@ static void __init szmem(void)
if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
(slot0sz << PAGE_SHIFT)) {
- printk("Ignoring slot %d onwards on node %d\n",
+ pr_info("Ignoring slot %d onwards on node %d\n",
slot, node);
slot = MAX_MEM_SLOTS;
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)
(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
slice * IP27_NMI_KREGS_CPU_SIZE);
- printk("NMI nasid %d: slice %d\n", nasid, slice);
+ pr_emerg("NMI nasid %d: slice %d\n", nasid, slice);
/*
* Saved main processor registers
*/
for (i = 0; i < 32; ) {
if ((i % 4) == 0)
- printk("$%2d :", i);
- printk(" %016lx", nr->gpr[i]);
+ pr_emerg("$%2d :", i);
+ pr_cont(" %016lx", nr->gpr[i]);
i++;
if ((i % 4) == 0)
- printk("\n");
+ pr_cont("\n");
}
- printk("Hi : (value lost)\n");
- printk("Lo : (value lost)\n");
+ pr_emerg("Hi : (value lost)\n");
+ pr_emerg("Lo : (value lost)\n");
/*
* Saved cp0 registers
*/
- printk("epc : %016lx %pS\n", nr->epc, (void *) nr->epc);
- printk("%s\n", print_tainted());
- printk("ErrEPC: %016lx %pS\n", nr->error_epc, (void *) nr->error_epc);
- printk("ra : %016lx %pS\n", nr->gpr[31], (void *) nr->gpr[31]);
- printk("Status: %08lx ", nr->sr);
+ pr_emerg("epc : %016lx %pS\n", nr->epc, (void *)nr->epc);
+ pr_emerg("%s\n", print_tainted());
+ pr_emerg("ErrEPC: %016lx %pS\n", nr->error_epc, (void *)nr->error_epc);
+ pr_emerg("ra : %016lx %pS\n", nr->gpr[31], (void *)nr->gpr[31]);
+ pr_emerg("Status: %08lx ", nr->sr);
if (nr->sr & ST0_KX)
- printk("KX ");
+ pr_cont("KX ");
if (nr->sr & ST0_SX)
- printk("SX ");
+ pr_cont("SX ");
if (nr->sr & ST0_UX)
- printk("UX ");
+ pr_cont("UX ");
switch (nr->sr & ST0_KSU) {
case KSU_USER:
- printk("USER ");
+ pr_cont("USER ");
break;
case KSU_SUPERVISOR:
- printk("SUPERVISOR ");
+ pr_cont("SUPERVISOR ");
break;
case KSU_KERNEL:
- printk("KERNEL ");
+ pr_cont("KERNEL ");
break;
default:
- printk("BAD_MODE ");
+ pr_cont("BAD_MODE ");
break;
}
if (nr->sr & ST0_ERL)
- printk("ERL ");
+ pr_cont("ERL ");
if (nr->sr & ST0_EXL)
- printk("EXL ");
+ pr_cont("EXL ");
if (nr->sr & ST0_IE)
- printk("IE ");
- printk("\n");
+ pr_cont("IE ");
+ pr_cont("\n");
- printk("Cause : %08lx\n", nr->cause);
- printk("PrId : %08x\n", read_c0_prid());
- printk("BadVA : %016lx\n", nr->badva);
- printk("CErr : %016lx\n", nr->cache_err);
- printk("NMI_SR: %016lx\n", nr->nmi_sr);
+ pr_emerg("Cause : %08lx\n", nr->cause);
+ pr_emerg("PrId : %08x\n", read_c0_prid());
+ pr_emerg("BadVA : %016lx\n", nr->badva);
+ pr_emerg("CErr : %016lx\n", nr->cache_err);
+ pr_emerg("NMI_SR: %016lx\n", nr->nmi_sr);
- printk("\n");
+ pr_emerg("\n");
}
void nmi_dump_hub_irq(nasid_t nasid, int slice)
{
- hubreg_t mask0, mask1, pend0, pend1;
+ u64 mask0, mask1, pend0, pend1;
if (slice == 0) { /* Slice A */
mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A);
@@ -143,9 +143,9 @@ void nmi_dump_hub_irq(nasid_t nasid, int slice)
pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);
pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);
- printk("PI_INT_MASK0: %16Lx PI_INT_MASK1: %16Lx\n", mask0, mask1);
- printk("PI_INT_PEND0: %16Lx PI_INT_PEND1: %16Lx\n", pend0, pend1);
- printk("\n\n");
+ pr_emerg("PI_INT_MASK0: %16llx PI_INT_MASK1: %16llx\n", mask0, mask1);
+ pr_emerg("PI_INT_PEND0: %16llx PI_INT_PEND1: %16llx\n", pend0, pend1);
+ pr_emerg("\n\n");
}
/*
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)
ip27_send_ipi_single(i, action);
}
-static void ip27_init_secondary(void)
+static void ip27_init_cpu(void)
{
per_cpu_init();
}
@@ -235,9 +235,10 @@ static void __init ip27_prepare_cpus(unsigned int max_cpus)
const struct plat_smp_ops ip27_smp_ops = {
.send_ipi_single = ip27_send_ipi_single,
.send_ipi_mask = ip27_send_ipi_mask,
- .init_secondary = ip27_init_secondary,
+ .init_secondary = ip27_init_cpu,
.smp_finish = ip27_smp_finish,
.boot_secondary = ip27_boot_secondary,
.smp_setup = ip27_smp_setup,
.prepare_cpus = ip27_prepare_cpus,
+ .prepare_boot_cpu = ip27_init_cpu,
};
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 @@
#include <asm/sn/sn0/hubio.h>
#include <asm/pci/bridge.h>
-static void enable_rt_irq(struct irq_data *d)
-{
-}
-
-static void disable_rt_irq(struct irq_data *d)
-{
-}
-
-static struct irq_chip rt_irq_type = {
- .name = "SN HUB RT timer",
- .irq_mask = disable_rt_irq,
- .irq_unmask = enable_rt_irq,
-};
-
static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
{
unsigned int cpu = smp_processor_id();
@@ -65,8 +51,6 @@ static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
}
-unsigned int rt_timer_irq;
-
static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
static DEFINE_PER_CPU(char [11], hub_rt_name);
@@ -87,6 +71,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
struct irqaction hub_rt_irqaction = {
.handler = hub_rt_counter_handler,
+ .percpu_dev_id = &hub_rt_clockevent,
.flags = IRQF_PERCPU | IRQF_TIMER,
.name = "hub-rt",
};
@@ -107,7 +92,6 @@ void hub_rt_clock_event_init(void)
unsigned int cpu = smp_processor_id();
struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
unsigned char *name = per_cpu(hub_rt_name, cpu);
- int irq = rt_timer_irq;
sprintf(name, "hub-rt %d", cpu);
cd->name = name;
@@ -118,29 +102,19 @@ void hub_rt_clock_event_init(void)
cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
cd->min_delta_ticks = 0x300;
cd->rating = 200;
- cd->irq = irq;
+ cd->irq = IP27_RT_TIMER_IRQ;
cd->cpumask = cpumask_of(cpu);
cd->set_next_event = rt_next_event;
clockevents_register_device(cd);
+
+ enable_percpu_irq(IP27_RT_TIMER_IRQ, IRQ_TYPE_NONE);
}
static void __init hub_rt_clock_event_global_init(void)
{
- int irq;
-
- do {
- smp_wmb();
- irq = rt_timer_irq;
- if (irq)
- break;
-
- irq = allocate_irqno();
- if (irq < 0)
- panic("Allocation of irq number for timer failed");
- } while (xchg(&rt_timer_irq, irq));
-
- irq_set_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
- setup_irq(irq, &hub_rt_irqaction);
+ irq_set_handler(IP27_RT_TIMER_IRQ, handle_percpu_devid_irq);
+ irq_set_percpu_devid(IP27_RT_TIMER_IRQ);
+ setup_percpu_irq(IP27_RT_TIMER_IRQ, &hub_rt_irqaction);
}
static u64 hub_rt_read(struct clocksource *cs)
@@ -194,8 +168,6 @@ void cpu_time_init(void)
panic("No information about myself?");
printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
-
- set_c0_status(SRB_TIMOCLK);
}
void 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)
return 0;
}
-void xtalk_probe_node(cnodeid_t nid)
+static void xtalk_probe_node(cnodeid_t nid)
{
volatile u64 hubreg;
nasid_t nasid;
@@ -133,3 +133,14 @@ void xtalk_probe_node(cnodeid_t nid)
break;
}
}
+
+static int __init xtalk_init(void)
+{
+ cnodeid_t cnode;
+
+ for_each_online_node(cnode)
+ xtalk_probe_node(cnode);
+
+ return 0;
+}
+arch_initcall(xtalk_init);
OpenPOWER on IntegriCloud