diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-22 19:30:30 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-22 19:30:30 +0300 |
commit | 5c6bd5de3c2e5bc8a17451e281ed2613375a7fd5 (patch) | |
tree | ec6af5a1dfddef30f92da4a2742bf3da04b520f9 /arch | |
parent | f7c3bf8fa7e5a8e45f4a8e82be6466157854b59b (diff) | |
parent | 05d013a0366d50f4f0dbebf8c1b22b42020bf49a (diff) | |
download | linux-5c6bd5de3c2e5bc8a17451e281ed2613375a7fd5.tar.xz |
Merge tag 'mips_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS updates from Paul Burton:
"Main MIPS changes:
- boot_mem_map is removed, providing a nice cleanup made possible by
the recent removal of bootmem.
- Some fixes to atomics, in general providing compiler barriers for
smp_mb__{before,after}_atomic plus fixes specific to Loongson CPUs
or MIPS32 systems using cmpxchg64().
- Conversion to the new generic VDSO infrastructure courtesy of
Vincenzo Frascino.
- Removal of undefined behavior in set_io_port_base(), fixing the
behavior of some MIPS kernel configurations when built with recent
clang versions.
- Initial MIPS32 huge page support, functional on at least Ingenic
SoCs.
- pte_special() is now supported for some configurations, allowing
among other things generic fast GUP to be used.
- Miscellaneous fixes & cleanups.
And platform specific changes:
- Major improvements to Ingenic SoC support from Paul Cercueil,
mostly enabled by the inclusion of the new TCU (timer-counter unit)
drivers he's spent a very patient year or so working on. Plus some
fixes for X1000 SoCs from Zhou Yanjie.
- Netgear R6200 v1 systems are now supported by the bcm47xx platform.
- DT updates for BMIPS, Lantiq & Microsemi Ocelot systems"
* tag 'mips_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (89 commits)
MIPS: Detect bad _PFN_SHIFT values
MIPS: Disable pte_special() for MIPS32 with RiXi
MIPS: ralink: deactivate PCI support for SOC_MT7621
mips: compat: vdso: Use legacy syscalls as fallback
MIPS: Drop Loongson _CACHE_* definitions
MIPS: tlbex: Remove cpu_has_local_ebase
MIPS: tlbex: Simplify r3k check
MIPS: Select R3k-style TLB in Kconfig
MIPS: PCI: refactor ioc3 special handling
mips: remove ioremap_cachable
mips/atomic: Fix smp_mb__{before,after}_atomic()
mips/atomic: Fix loongson_llsc_mb() wreckage
mips/atomic: Fix cmpxchg64 barriers
MIPS: Octeon: remove duplicated include from dma-octeon.c
firmware: bcm47xx_nvram: Allow COMPILE_TEST
firmware: bcm47xx_nvram: Correct size_t printf format
MIPS: Treat Loongson Extensions as ASEs
MIPS: Remove dev_err() usage after platform_get_irq()
MIPS: dts: mscc: describe the PTP ready interrupt
MIPS: dts: mscc: describe the PTP register range
...
Diffstat (limited to 'arch')
103 files changed, 1586 insertions, 2303 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 904c096fa4da..cc8e2b1032a5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -22,6 +22,7 @@ config MIPS select GENERIC_CLOCKEVENTS select GENERIC_CMOS_UPDATE select GENERIC_CPU_AUTOPROBE + select GENERIC_GETTIMEOFDAY select GENERIC_IOMAP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW @@ -43,7 +44,7 @@ config MIPS select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK - select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT + select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES select HAVE_ASM_MODVERSIONS select HAVE_EBPF_JIT if (!CPU_MICROMIPS) select HAVE_CONTEXT_TRACKING @@ -75,6 +76,7 @@ config MIPS select HAVE_STACKPROTECTOR select HAVE_SYSCALL_TRACEPOINTS select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP + select HAVE_GENERIC_VDSO select IRQ_FORCED_THREADING select ISA if EISA select MODULES_USE_ELF_RELA if MODULES && 64BIT @@ -83,6 +85,7 @@ config MIPS select RTC_LIB select SYSCTL_EXCEPTION_TRACE select VIRT_TO_BUS + select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI) menu "Machine selection" @@ -385,6 +388,7 @@ config MACH_INGENIC select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_ZBOOT_UART16550 + select CPU_SUPPORTS_HUGEPAGES select DMA_NONCOHERENT select IRQ_MIPS_CPU select PINCTRL @@ -1231,7 +1235,7 @@ config SYS_SUPPORTS_LITTLE_ENDIAN config SYS_SUPPORTS_HUGETLBFS bool - depends on CPU_SUPPORTS_HUGEPAGES && 64BIT + depends on CPU_SUPPORTS_HUGEPAGES default y config MIPS_HUGE_TLB_SUPPORT @@ -1579,6 +1583,7 @@ config CPU_R3000 depends on SYS_HAS_CPU_R3000 select CPU_HAS_WB select CPU_HAS_LOAD_STORE_LR + select CPU_R3K_TLB select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_HIGHMEM help @@ -1594,6 +1599,7 @@ config CPU_TX39XX depends on SYS_HAS_CPU_TX39XX select CPU_SUPPORTS_32BIT_KERNEL select CPU_HAS_LOAD_STORE_LR + select CPU_R3K_TLB config CPU_VR41XX bool "R41xx" @@ -1607,15 +1613,6 @@ config CPU_VR41XX kernel built with this option will not run on any other type of processor or vice versa. -config CPU_R4300 - bool "R4300" - depends on SYS_HAS_CPU_R4300 - select CPU_SUPPORTS_32BIT_KERNEL - select CPU_SUPPORTS_64BIT_KERNEL - select CPU_HAS_LOAD_STORE_LR - help - MIPS Technologies R4300-series processors. - config CPU_R4X00 bool "R4x00" depends on SYS_HAS_CPU_R4X00 @@ -1646,14 +1643,6 @@ config CPU_R5000 help MIPS Technologies R5000-series processors other than the Nevada. -config CPU_R5432 - bool "R5432" - depends on SYS_HAS_CPU_R5432 - select CPU_SUPPORTS_32BIT_KERNEL - select CPU_SUPPORTS_64BIT_KERNEL - select CPU_SUPPORTS_HUGEPAGES - select CPU_HAS_LOAD_STORE_LR - config CPU_R5500 bool "R5500" depends on SYS_HAS_CPU_R5500 @@ -1675,16 +1664,6 @@ config CPU_NEVADA help QED / PMC-Sierra RM52xx-series ("Nevada") processors. -config CPU_R8000 - bool "R8000" - depends on SYS_HAS_CPU_R8000 - select CPU_HAS_PREFETCH - select CPU_HAS_LOAD_STORE_LR - select CPU_SUPPORTS_64BIT_KERNEL - help - MIPS Technologies R8000 processors. Note these processors are - uncommon and the support for them is incomplete. - config CPU_R10000 bool "R10000" depends on SYS_HAS_CPU_R10000 @@ -1977,9 +1956,6 @@ config SYS_HAS_CPU_TX39XX config SYS_HAS_CPU_VR41XX bool -config SYS_HAS_CPU_R4300 - bool - config SYS_HAS_CPU_R4X00 bool @@ -1989,18 +1965,12 @@ config SYS_HAS_CPU_TX49XX config SYS_HAS_CPU_R5000 bool -config SYS_HAS_CPU_R5432 - bool - config SYS_HAS_CPU_R5500 bool config SYS_HAS_CPU_NEVADA bool -config SYS_HAS_CPU_R8000 - bool - config SYS_HAS_CPU_R10000 bool select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT @@ -2118,6 +2088,7 @@ config CPU_SUPPORTS_ADDRWINCFG bool config CPU_SUPPORTS_HUGEPAGES bool + depends on !(32BIT && (ARCH_PHYS_ADDR_T_64BIT || EVA)) config CPU_SUPPORTS_UNCACHED_ACCELERATED bool config MIPS_PGD_C0_CONTEXT @@ -2200,13 +2171,13 @@ config PAGE_SIZE_4KB config PAGE_SIZE_8KB bool "8kB" - depends on CPU_R8000 || CPU_CAVIUM_OCTEON + depends on CPU_CAVIUM_OCTEON depends on !MIPS_VA_BITS_48 help Using 8kB page size will result in higher performance kernel at the price of higher memory consumption. This option is available - only on R8000 and cnMIPS processors. Note that you will need a - suitable Linux distribution to support this. + only on cnMIPS processors. Note that you will need a suitable Linux + distribution to support this. config PAGE_SIZE_16KB bool "16kB" @@ -2297,7 +2268,7 @@ config CPU_HAS_PREFETCH config CPU_GENERIC_DUMP_TLB bool - default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX) + default y if !(CPU_R3000 || CPU_TX39XX) config MIPS_FP_SUPPORT bool "Floating Point support" if EXPERT @@ -2319,6 +2290,9 @@ config CPU_R2300_FPU depends on MIPS_FP_SUPPORT default y if CPU_R3000 || CPU_TX39XX +config CPU_R3K_TLB + bool + config CPU_R4K_FPU bool depends on MIPS_FP_SUPPORT @@ -2326,7 +2300,7 @@ config CPU_R4K_FPU config CPU_R4K_CACHE_TLB bool - default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON) + default y if !(CPU_R3K_TLB || CPU_SB1 || CPU_CAVIUM_OCTEON) config MIPS_MT_SMP bool "MIPS MT SMP support (1 TC on each available VPE)" @@ -2583,7 +2557,6 @@ config CPU_R4400_WORKAROUNDS config MIPS_ASID_SHIFT int default 6 if CPU_R3000 || CPU_TX39XX - default 4 if CPU_R8000 default 0 config MIPS_ASID_BITS @@ -3077,10 +3050,6 @@ config STACKTRACE_SUPPORT bool default y -config HAVE_LATENCYTOP_SUPPORT - bool - default y - config PGTABLE_LEVELS int default 4 if PAGE_SIZE_4KB && MIPS_VA_BITS_48 diff --git a/arch/mips/Makefile b/arch/mips/Makefile index eceff9b75b22..cdc09b71febe 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -163,7 +163,6 @@ cflags-y += -fno-stack-check # cflags-$(CONFIG_CPU_R3000) += -march=r3000 cflags-$(CONFIG_CPU_TX39XX) += -march=r3900 -cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap @@ -174,8 +173,6 @@ cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap cflags-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,--trap cflags-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,--trap cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap -cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \ - -Wa,--trap cflags-$(CONFIG_CPU_R5500) += $(call cc-option,-march=r5500,-march=r5000) \ -Wa,--trap cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ @@ -186,7 +183,6 @@ cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \ -Wa,--trap cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mdmx) cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mips3d) -cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \ -Wa,--trap cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c index a80910d2738c..35266a70e22a 100644 --- a/arch/mips/bcm47xx/board.c +++ b/arch/mips/bcm47xx/board.c @@ -160,6 +160,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = { {{BCM47XX_BOARD_LUXUL_XVW_P30_V1, "Luxul XVW-P30 V1"}, "luxul_xvwp30_v1"}, {{BCM47XX_BOARD_LUXUL_XWR_600_V1, "Luxul XWR-600 V1"}, "luxul_xwr600_v1"}, {{BCM47XX_BOARD_LUXUL_XWR_1750_V1, "Luxul XWR-1750 V1"}, "luxul_xwr1750_v1"}, + {{BCM47XX_BOARD_NETGEAR_R6200_V1, "Netgear R6200 V1"}, "U12H192T00_NETGEAR"}, {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"}, {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"}, {{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"}, diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c index 67b6a78d670b..535d84addcdb 100644 --- a/arch/mips/bcm47xx/buttons.c +++ b/arch/mips/bcm47xx/buttons.c @@ -385,6 +385,13 @@ bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = { /* Netgear */ static const struct gpio_keys_button +bcm47xx_buttons_netgear_r6200_v1[] __initconst = { + BCM47XX_GPIO_KEY(2, KEY_RFKILL), + BCM47XX_GPIO_KEY(3, KEY_RESTART), + BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), +}; + +static const struct gpio_keys_button bcm47xx_buttons_netgear_wndr3400v1[] __initconst = { BCM47XX_GPIO_KEY(4, KEY_RESTART), BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), @@ -664,6 +671,9 @@ int __init bcm47xx_buttons_register(void) err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gv2v3); break; + case BCM47XX_BOARD_NETGEAR_R6200_V1: + err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_r6200_v1); + break; case BCM47XX_BOARD_NETGEAR_WNDR3400V1: err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1); break; diff --git a/arch/mips/boot/dts/brcm/bcm3368.dtsi b/arch/mips/boot/dts/brcm/bcm3368.dtsi index 7a3e5c8943ca..69cbef472377 100644 --- a/arch/mips/boot/dts/brcm/bcm3368.dtsi +++ b/arch/mips/boot/dts/brcm/bcm3368.dtsi @@ -51,16 +51,22 @@ compatible = "simple-bus"; ranges; - periph_cntl: syscon@fff8c000 { + clkctl: clock-controller@fff8c004 { + compatible = "brcm,bcm3368-clocks"; + reg = <0xfff8c004 0x4>; + #clock-cells = <1>; + }; + + periph_cntl: syscon@fff8c008 { compatible = "syscon"; - reg = <0xfff8c000 0xc>; + reg = <0xfff8c000 0x4>; native-endian; }; reboot: syscon-reboot@fff8c008 { compatible = "syscon-reboot"; regmap = <&periph_cntl>; - offset = <0x8>; + offset = <0x0>; mask = <0x1>; }; diff --git a/arch/mips/boot/dts/brcm/bcm63268.dtsi b/arch/mips/boot/dts/brcm/bcm63268.dtsi index 58790b173bb2..beec24145af7 100644 --- a/arch/mips/boot/dts/brcm/bcm63268.dtsi +++ b/arch/mips/boot/dts/brcm/bcm63268.dtsi @@ -51,16 +51,22 @@ compatible = "simple-bus"; ranges; - periph_cntl: syscon@10000000 { + clkctl: clock-controller@10000004 { + compatible = "brcm,bcm63268-clocks"; + reg = <0x10000004 0x4>; + #clock-cells = <1>; + }; + + periph_cntl: syscon@10000008 { compatible = "syscon"; - reg = <0x10000000 0x14>; + reg = <0x10000000 0xc>; native-endian; }; reboot: syscon-reboot@10000008 { compatible = "syscon-reboot"; regmap = <&periph_cntl>; - offset = <0x8>; + offset = <0x0>; mask = <0x1>; }; diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi index bf6716aa425a..af860d06def6 100644 --- a/arch/mips/boot/dts/brcm/bcm6328.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi @@ -51,6 +51,12 @@ compatible = "simple-bus"; ranges; + clkctl: clock-controller@10000004 { + compatible = "brcm,bcm6328-clocks"; + reg = <0x10000004 0x4>; + #clock-cells = <1>; + }; + periph_intc: interrupt-controller@10000020 { compatible = "brcm,bcm6345-l1-intc"; reg = <0x10000020 0x10>, diff --git a/arch/mips/boot/dts/brcm/bcm6358.dtsi b/arch/mips/boot/dts/brcm/bcm6358.dtsi index 26ddae5a4247..f21176cac038 100644 --- a/arch/mips/boot/dts/brcm/bcm6358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6358.dtsi @@ -51,16 +51,22 @@ compatible = "simple-bus"; ranges; - periph_cntl: syscon@fffe0000 { + clkctl: clock-controller@fffe0004 { + compatible = "brcm,bcm6358-clocks"; + reg = <0xfffe0004 0x4>; + #clock-cells = <1>; + }; + + periph_cntl: syscon@fffe0008 { compatible = "syscon"; - reg = <0xfffe0000 0xc>; + reg = <0xfffe0000 0x4>; native-endian; }; reboot: syscon-reboot@fffe0008 { compatible = "syscon-reboot"; regmap = <&periph_cntl>; - offset = <0x8>; + offset = <0x0>; mask = <0x1>; }; diff --git a/arch/mips/boot/dts/brcm/bcm6362.dtsi b/arch/mips/boot/dts/brcm/bcm6362.dtsi index c387793525dd..8ae6981735b8 100644 --- a/arch/mips/boot/dts/brcm/bcm6362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6362.dtsi @@ -51,16 +51,22 @@ compatible = "simple-bus"; ranges; - periph_cntl: syscon@10000000 { + clkctl: clock-controller@10000004 { + compatible = "brcm,bcm6362-clocks"; + reg = <0x10000004 0x4>; + #clock-cells = <1>; + }; + + periph_cntl: syscon@10000008 { compatible = "syscon"; - reg = <0x10000000 0x14>; + reg = <0x10000000 0xc>; native-endian; }; reboot: syscon-reboot@10000008 { compatible = "syscon-reboot"; regmap = <&periph_cntl>; - offset = <0x8>; + offset = <0x0>; mask = <0x1>; }; diff --git a/arch/mips/boot/dts/brcm/bcm6368.dtsi b/arch/mips/boot/dts/brcm/bcm6368.dtsi index e116a385525f..449c167dd892 100644 --- a/arch/mips/boot/dts/brcm/bcm6368.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6368.dtsi @@ -51,16 +51,22 @@ compatible = "simple-bus"; ranges; - periph_cntl: syscon@10000000 { + clkctl: clock-controller@10000004 { + compatible = "brcm,bcm6368-clocks"; + reg = <0x10000004 0x4>; + #clock-cells = <1>; + }; + + periph_cntl: syscon@100000008 { compatible = "syscon"; - reg = <0x10000000 0x14>; + reg = <0x10000000 0xc>; native-endian; }; reboot: syscon-reboot@10000008 { compatible = "syscon-reboot"; regmap = <&periph_cntl>; - offset = <0x8>; + offset = <0x0>; mask = <0x1>; }; diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index 4f7b1fa31cf5..2e9952311ecd 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts @@ -2,6 +2,7 @@ /dts-v1/; #include "jz4780.dtsi" +#include <dt-bindings/clock/ingenic,tcu.h> #include <dt-bindings/gpio/gpio.h> / { @@ -238,3 +239,9 @@ bias-disable; }; }; + +&tcu { + /* 3 MHz for the system timer and clocksource */ + assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER1>; + assigned-clock-rates = <3000000>, <3000000>; +}; diff --git a/arch/mips/boot/dts/ingenic/gcw0.dts b/arch/mips/boot/dts/ingenic/gcw0.dts index 35f0291e8d38..f58d239c2058 100644 --- a/arch/mips/boot/dts/ingenic/gcw0.dts +++ b/arch/mips/boot/dts/ingenic/gcw0.dts @@ -2,6 +2,7 @@ /dts-v1/; #include "jz4770.dtsi" +#include <dt-bindings/clock/ingenic,tcu.h> / { compatible = "gcw,zero", "ingenic,jz4770"; @@ -60,3 +61,12 @@ /* The WiFi module is connected to the UHC. */ status = "okay"; }; + +&tcu { + /* 750 kHz for the system timer and clocksource */ + assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER2>; + assigned-clock-rates = <750000>, <750000>; + + /* PWM1 is in use, so reserve channel #2 for the clocksource */ + ingenic,pwm-channels-mask = <0xfa>; +}; diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi index 2beb78a62b7d..5accda2767be 100644 --- a/arch/mips/boot/dts/ingenic/jz4740.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi @@ -53,6 +53,28 @@ clock-names = "rtc"; }; + tcu: timer@10002000 { + compatible = "ingenic,jz4740-tcu", "simple-mfd"; + reg = <0x10002000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x10002000 0x1000>; + + #clock-cells = <1>; + + clocks = <&cgu JZ4740_CLK_RTC + &cgu JZ4740_CLK_EXT + &cgu JZ4740_CLK_PCLK + &cgu JZ4740_CLK_TCU>; + clock-names = "rtc", "ext", "pclk", "tcu"; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&intc>; + interrupts = <23 22 21>; + }; + rtc_dev: rtc@10003000 { compatible = "ingenic,jz4740-rtc"; reg = <0x10003000 0x40>; @@ -132,6 +154,53 @@ }; }; + aic: audio-controller@10020000 { + compatible = "ingenic,jz4740-i2s"; + reg = <0x10020000 0x38>; + + #sound-dai-cells = <0>; + + interrupt-parent = <&intc>; + interrupts = <18>; + + clocks = <&cgu JZ4740_CLK_AIC>, + <&cgu JZ4740_CLK_I2S>, + <&cgu JZ4740_CLK_EXT>, + <&cgu JZ4740_CLK_PLL_HALF>; + clock-names = "aic", "i2s", "ext", "pll half"; + + dmas = <&dmac 25 0xffffffff>, <&dmac 24 0xffffffff>; + dma-names = "rx", "tx"; + }; + + codec: audio-codec@100200a4 { + compatible = "ingenic,jz4740-codec"; + reg = <0x10020080 0x8>; + + #sound-dai-cells = <0>; + + clocks = <&cgu JZ4740_CLK_AIC>; + clock-names = "aic"; + }; + + mmc: mmc@10021000 { + compatible = "ingenic,jz4740-mmc"; + reg = <0x10021000 0x1000>; + + clocks = <&cgu JZ4740_CLK_MMC>; + clock-names = "mmc"; + + interrupt-parent = <&intc>; + interrupts = <14>; + + dmas = <&dmac 27 0xffffffff>, <&dmac 26 0xffffffff>; + dma-names = "rx", "tx"; + + cap-sd-highspeed; + cap-mmc-highspeed; + cap-sdio-irq; + }; + uart0: serial@10030000 { compatible = "ingenic,jz4740-uart"; reg = <0x10030000 0x100>; @@ -154,6 +223,38 @@ clock-names = "baud", "module"; }; + adc: adc@10070000 { + compatible = "ingenic,jz4740-adc"; + reg = <0x10070000 0x30>; + #io-channel-cells = <1>; + + clocks = <&cgu JZ4740_CLK_ADC>; + clock-names = "adc"; + + interrupt-parent = <&intc>; + interrupts = <12>; + }; + + nemc: memory-controller@13010000 { + compatible = "ingenic,jz4740-nemc"; + reg = <0x13010000 0x54>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <1 0 0x18000000 0x4000000 + 2 0 0x14000000 0x4000000 + 3 0 0x0c000000 0x4000000 + 4 0 0x08000000 0x4000000>; + + clocks = <&cgu JZ4740_CLK_MCLK>; + }; + + ecc: ecc-controller@13010100 { + compatible = "ingenic,jz4740-ecc"; + reg = <0x13010100 0x2C>; + + clocks = <&cgu JZ4740_CLK_MCLK>; + }; + dmac: dma-controller@13020000 { compatible = "ingenic,jz4740-dma"; reg = <0x13020000 0xbc @@ -164,9 +265,6 @@ interrupts = <20>; clocks = <&cgu JZ4740_CLK_DMA>; - - /* Disable dmac until we have something that uses it */ - status = "disabled"; }; uhc: uhc@13030000 { @@ -182,4 +280,27 @@ status = "disabled"; }; + + udc: usb@13040000 { + compatible = "ingenic,jz4740-musb"; + reg = <0x13040000 0x10000>; + + interrupt-parent = <&intc>; + interrupts = <24>; + interrupt-names = "mc"; + + clocks = <&cgu JZ4740_CLK_UDC>; + clock-names = "udc"; + }; + + lcd: lcd-controller@13050000 { + compatible = "ingenic,jz4740-lcd"; + reg = <0x13050000 0x1000>; + + interrupt-parent = <&intc>; + interrupts = <30>; + + clocks = <&cgu JZ4740_CLK_LCD_PCLK>, <&cgu JZ4740_CLK_LCD>; + clock-names = "lcd_pclk", "lcd"; + }; }; diff --git a/arch/mips/boot/dts/ingenic/jz4770.dtsi b/arch/mips/boot/dts/ingenic/jz4770.dtsi index 49ede6c14ff3..0bfb9edff3d0 100644 --- a/arch/mips/boot/dts/ingenic/jz4770.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4770.dtsi @@ -46,6 +46,27 @@ #clock-cells = <1>; }; + tcu: timer@10002000 { + compatible = "ingenic,jz4770-tcu", "simple-mfd"; + reg = <0x10002000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x10002000 0x1000>; + + #clock-cells = <1>; + + clocks = <&cgu JZ4770_CLK_RTC + &cgu JZ4770_CLK_EXT + &cgu JZ4770_CLK_PCLK>; + clock-names = "rtc", "ext", "pclk"; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&intc>; + interrupts = <27 26 25>; + }; + pinctrl: pin-controller@10010000 { compatible = "ingenic,jz4770-pinctrl"; reg = <0x10010000 0x600>; diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi index b03cdec56de9..c54bd7cfec55 100644 --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi @@ -46,6 +46,29 @@ #clock-cells = <1>; }; + tcu: timer@10002000 { + compatible = "ingenic,jz4780-tcu", + "ingenic,jz4770-tcu", + "simple-mfd"; + reg = <0x10002000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x10002000 0x1000>; + + #clock-cells = <1>; + + clocks = <&cgu JZ4780_CLK_RTCLK + &cgu JZ4780_CLK_EXCLK + &cgu JZ4780_CLK_PCLK>; + clock-names = "rtc", "ext", "pclk"; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&intc>; + interrupts = <27 26 25>; + }; + rtc_dev: rtc@10003000 { compatible = "ingenic,jz4780-rtc"; reg = <0x10003000 0x4c>; diff --git a/arch/mips/boot/dts/ingenic/qi_lb60.dts b/arch/mips/boot/dts/ingenic/qi_lb60.dts index 76aaf8982554..7a371d9c5a33 100644 --- a/arch/mips/boot/dts/ingenic/qi_lb60.dts +++ b/arch/mips/boot/dts/ingenic/qi_lb60.dts @@ -3,12 +3,231 @@ #include "jz4740.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/iio/adc/ingenic,adc.h> +#include <dt-bindings/clock/ingenic,tcu.h> +#include <dt-bindings/input/input.h> + +#define KEY_QI_QI KEY_F13 +#define KEY_QI_UPRED KEY_RIGHTALT +#define KEY_QI_VOLUP KEY_VOLUMEUP +#define KEY_QI_VOLDOWN KEY_VOLUMEDOWN +#define KEY_QI_FN KEY_LEFTCTRL + / { compatible = "qi,lb60", "ingenic,jz4740"; chosen { stdout-path = &uart0; }; + + vcc: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vcc"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + mmc_power: regulator@1 { + compatible = "regulator-fixed"; + regulator-name = "mmc_vcc"; + gpio = <&gpd 2 0>; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + amp_supply: regulator@2 { + compatible = "regulator-fixed"; + regulator-name = "amp_supply"; + gpio = <&gpd 4 0>; + enable-active-high; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + amp: analog-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpb 29 GPIO_ACTIVE_HIGH>; + VCC-supply = <&_supply>; + }; + + sound { + compatible = "simple-audio-card"; + + simple-audio-card,name = "QI LB60"; + simple-audio-card,format = "i2s"; + + simple-audio-card,widgets = + "Speaker", "Speaker", + "Microphone", "Mic"; + simple-audio-card,routing = + "MIC", "Mic", + "Speaker", "OUTL", + "Speaker", "OUTR", + "INL", "LOUT", + "INL", "ROUT"; + + simple-audio-card,aux-devs = <&>; + + simple-audio-card,bitclock-master = <&dai_codec>; + simple-audio-card,frame-master = <&dai_codec>; + + dai_cpu: simple-audio-card,cpu { + sound-dai = <&aic>; + }; + + dai_codec: simple-audio-card,codec { + sound-dai = <&codec>; + }; + }; + + keys { + compatible = "gpio-keys"; + + key { + label = "Power"; + wakeup-source; + linux,code = <KEY_POWER>; + gpios = <&gpd 29 GPIO_ACTIVE_LOW>; + }; + }; + + keyboard { + compatible = "gpio-matrix-keypad"; + + col-scan-delay-us = <10>; + debounce-delay-ms = <10>; + wakeup-source; + + row-gpios = <&gpd 18 0 &gpd 19 0 &gpd 20 0 &gpd 21 0 + &gpd 22 0 &gpd 23 0 &gpd 24 0 &gpd 26 0>; + col-gpios = <&gpc 10 0 &gpc 11 0 &gpc 12 0 &gpc 13 0 + &gpc 14 0 &gpc 15 0 &gpc 16 0 &gpc 17 0>; + gpio-activelow; + + linux,keymap = < + MATRIX_KEY(0, 0, KEY_F1) /* S2 */ + MATRIX_KEY(0, 1, KEY_F2) /* S3 */ + MATRIX_KEY(0, 2, KEY_F3) /* S4 */ + MATRIX_KEY(0, 3, KEY_F4) /* S5 */ + MATRIX_KEY(0, 4, KEY_F5) /* S6 */ + MATRIX_KEY(0, 5, KEY_F6) /* S7 */ + MATRIX_KEY(0, 6, KEY_F7) /* S8 */ + + MATRIX_KEY(1, 0, KEY_Q) /* S10 */ + MATRIX_KEY(1, 1, KEY_W) /* S11 */ + MATRIX_KEY(1, 2, KEY_E) /* S12 */ + MATRIX_KEY(1, 3, KEY_R) /* S13 */ + MATRIX_KEY(1, 4, KEY_T) /* S14 */ + MATRIX_KEY(1, 5, KEY_Y) /* S15 */ + MATRIX_KEY(1, 6, KEY_U) /* S16 */ + MATRIX_KEY(1, 7, KEY_I) /* S17 */ + MATRIX_KEY(2, 0, KEY_A) /* S18 */ + MATRIX_KEY(2, 1, KEY_S) /* S19 */ + MATRIX_KEY(2, 2, KEY_D) /* S20 */ + MATRIX_KEY(2, 3, KEY_F) /* S21 */ + MATRIX_KEY(2, 4, KEY_G) /* S22 */ + MATRIX_KEY(2, 5, KEY_H) /* S23 */ + MATRIX_KEY(2, 6, KEY_J) /* S24 */ + MATRIX_KEY(2, 7, KEY_K) /* S25 */ + MATRIX_KEY(3, 0, KEY_ESC) /* S26 */ + MATRIX_KEY(3, 1, KEY_Z) /* S27 */ + MATRIX_KEY(3, 2, KEY_X) /* S28 */ + MATRIX_KEY(3, 3, KEY_C) /* S29 */ + MATRIX_KEY(3, 4, KEY_V) /* S30 */ + MATRIX_KEY(3, 5, KEY_B) /* S31 */ + MATRIX_KEY(3, 6, KEY_N) /* S32 */ + MATRIX_KEY(3, 7, KEY_M) /* S33 */ + MATRIX_KEY(4, 0, KEY_TAB) /* S34 */ + MATRIX_KEY(4, 1, KEY_CAPSLOCK) /* S35 */ + MATRIX_KEY(4, 2, KEY_BACKSLASH) /* S36 */ + MATRIX_KEY(4, 3, KEY_APOSTROPHE) /* S37 */ + MATRIX_KEY(4, 4, KEY_COMMA) /* S38 */ + MATRIX_KEY(4, 5, KEY_DOT) /* S39 */ + MATRIX_KEY(4, 6, KEY_SLASH) /* S40 */ + MATRIX_KEY(4, 7, KEY_UP) /* S41 */ + MATRIX_KEY(5, 0, KEY_O) /* S42 */ + MATRIX_KEY(5, 1, KEY_L) /* S43 */ + MATRIX_KEY(5, 2, KEY_EQUAL) /* S44 */ + MATRIX_KEY(5, 3, KEY_QI_UPRED) /* S45 */ + MATRIX_KEY(5, 4, KEY_SPACE) /* S46 */ + MATRIX_KEY(5, 5, KEY_QI_QI) /* S47 */ + MATRIX_KEY(5, 6, KEY_RIGHTCTRL) /* S48 */ + MATRIX_KEY(5, 7, KEY_LEFT) /* S49 */ + MATRIX_KEY(6, 0, KEY_F8) /* S50 */ + MATRIX_KEY(6, 1, KEY_P) /* S51 */ + MATRIX_KEY(6, 2, KEY_BACKSPACE)/* S52 */ + MATRIX_KEY(6, 3, KEY_ENTER) /* S53 */ + MATRIX_KEY(6, 4, KEY_QI_VOLUP) /* S54 */ + MATRIX_KEY(6, 5, KEY_QI_VOLDOWN) /* S55 */ + MATRIX_KEY(6, 6, KEY_DOWN) /* S56 */ + MATRIX_KEY(6, 7, KEY_RIGHT) /* S57 */ + + MATRIX_KEY(7, 0, KEY_LEFTSHIFT) /* S58 */ + MATRIX_KEY(7, 1, KEY_LEFTALT) /* S59 */ + MATRIX_KEY(7, 2, KEY_QI_FN) /* S60 */ + >; + }; + + spi { + compatible = "spi-gpio"; + #address-cells = <1>; + #size-cells = <0>; + + sck-gpios = <&gpc 23 GPIO_ACTIVE_HIGH>; + mosi-gpios = <&gpc 22 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpc 21 GPIO_ACTIVE_LOW>; + num-chipselects = <1>; + }; + + usb_charger: charger { + compatible = "gpio-charger"; + charger-type = "usb-sdp"; + gpios = <&gpd 28 GPIO_ACTIVE_LOW>; + status-gpios = <&gpc 27 GPIO_ACTIVE_LOW>; + }; + + simple_battery: battery { + compatible = "simple-battery"; + voltage-min-design-microvolt = <3600000>; + voltage-max-design-microvolt = <4200000>; + }; + + pmu { + compatible = "ingenic,jz4740-battery"; + io-channels = <&adc INGENIC_ADC_BATTERY>; + io-channel-names = "battery"; + power-supplies = <&usb_charger>; + monitored-battery = <&simple_battery>; + }; + + hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc INGENIC_ADC_AUX>; + }; + + panel: panel { + compatible = "giantplus,gpm940b0"; + + power-supply = <&vcc>; + + port { + panel_input: endpoint { + remote-endpoint = <&panel_output>; + }; + }; + }; + + usb_phy: usb-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + + vcc-supply = <&vcc>; + }; }; &ext { @@ -24,10 +243,116 @@ pinctrl-0 = <&pins_uart0>; }; +&uart1 { + status = "disabled"; +}; + +&nemc { + nandc: nand-controller@1 { + compatible = "ingenic,jz4740-nand"; + reg = <1 0 0x4000000>; + + #address-cells = <1>; + #size-cells = <0>; + + ingenic,bch-controller = <&ecc>; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_nemc>; + + rb-gpios = <&gpc 30 GPIO_ACTIVE_LOW>; + + nand@1 { + reg = <1>; + + nand-ecc-step-size = <512>; + nand-ecc-strength = <4>; + nand-ecc-mode = "hw"; + nand-is-boot-medium; + nand-on-flash-bbt; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "boot"; + reg = <0x0 0x400000>; + }; + + partition@400000 { + label = "kernel"; + reg = <0x400000 0x400000>; + }; + + partition@800000 { + label = "rootfs"; + reg = <0x800000 0x0>; + }; + }; + }; + }; +}; + +&lcd { + pinctrl-names = "default"; + pinctrl-0 = <&pins_lcd>; + + port { + panel_output: endpoint { + remote-endpoint = <&panel_input>; + }; + }; +}; + +&udc { + phys = <&usb_phy>; +}; + &pinctrl { + pins_lcd: lcd { + function = "lcd"; + groups = "lcd-8bit"; + }; + + pins_nemc: nemc { + function = "nand"; + groups = "nand-cs1"; + }; + pins_uart0: uart0 { function = "uart0"; groups = "uart0-data"; bias-disable; }; + + pins_mmc: mmc { + mmc { + function = "mmc"; + groups = "mmc-1bit", "mmc-4bit"; + bias-disable; + }; + + mmc-gpios { + pins = "PD0", "PD2"; + bias-disable; + }; + }; +}; + +&mmc { + bus-width = <4>; + max-frequency = <24000000>; + cd-gpios = <&gpd 0 GPIO_ACTIVE_HIGH>; + vmmc-supply = <&mmc_power>; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_mmc>; +}; + +&tcu { + /* 750 kHz for the system timer and clocksource */ + assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER1>; + assigned-clock-rates = <750000>, <750000>; }; diff --git a/arch/mips/boot/dts/mscc/ocelot.dtsi b/arch/mips/boot/dts/mscc/ocelot.dtsi index 33ae74aaa1bb..797d336db54d 100644 --- a/arch/mips/boot/dts/mscc/ocelot.dtsi +++ b/arch/mips/boot/dts/mscc/ocelot.dtsi @@ -120,6 +120,7 @@ reg = <0x1010000 0x10000>, <0x1030000 0x10000>, <0x1080000 0x100>, + <0x10e0000 0x10000>, <0x11e0000 0x100>, <0x11f0000 0x100>, <0x1200000 0x100>, @@ -134,12 +135,12 @@ <0x1800000 0x80000>, <0x1880000 0x10000>, <0x1060000 0x10000>; - reg-names = "sys", "rew", "qs", "port0", "port1", + reg-names = "sys", "rew", "qs", "ptp", "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7", "port8", "port9", "port10", "qsys", "ana", "s2"; - interrupts = <21 22>; - interrupt-names = "xtr", "inj"; + interrupts = <18 21 22>; + interrupt-names = "ptp_rdy", "xtr", "inj"; ethernet-ports { #address-cells = <1>; diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index 11d5a4e90736..14ea680d180e 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -190,7 +190,7 @@ char *octeon_swiotlb; void __init plat_swiotlb_setup(void) { - int i; + struct memblock_region *mem; phys_addr_t max_addr; phys_addr_t addr_size; size_t swiotlbsize; @@ -199,19 +199,15 @@ void __init plat_swiotlb_setup(void) max_addr = 0; addr_size = 0; - for (i = 0 ; i < boot_mem_map.nr_map; i++) { - struct boot_mem_map_entry *e = &boot_mem_map.map[i]; - if (e->type != BOOT_MEM_RAM && e->type != BOOT_MEM_INIT_RAM) - continue; - + for_each_memblock(memory, mem) { /* These addresses map low for PCI. */ - if (e->addr > 0x410000000ull && !OCTEON_IS_OCTEON2()) + if (mem->base > 0x410000000ull && !OCTEON_IS_OCTEON2()) continue; - addr_size += e->size; + addr_size += mem->size; - if (max_addr < e->addr + e->size) - max_addr = e->addr + e->size; + if (max_addr < mem->base + mem->size) + max_addr = mem->base + mem->size; } diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 8bf43c5a7bc7..95034bf5ca83 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -1007,8 +1007,7 @@ void __init plat_mem_setup(void) * regions next to each other. */ cvmx_bootmem_lock(); - while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX) - && (total < max_memory)) { + while (total < max_memory) { memory = cvmx_bootmem_phy_alloc(mem_alloc_size, __pa_symbol(&_end), -1, 0x100000, diff --git a/arch/mips/configs/qi_lb60_defconfig b/arch/mips/configs/qi_lb60_defconfig index 208da8a55f48..d3f4d5248d9f 100644 --- a/arch/mips/configs/qi_lb60_defconfig +++ b/arch/mips/configs/qi_lb60_defconfig @@ -1,7 +1,6 @@ # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y # CONFIG_CROSS_MEMORY_ATTACH is not set -CONFIG_PREEMPT=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS_ALL=y @@ -17,9 +16,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_PARTITION_ADVANCED=y # CONFIG_EFI_PARTITION is not set -# CONFIG_IOSCHED_CFQ is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_COMPACTION is not set +CONFIG_CMA=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -31,9 +29,6 @@ CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_DIAG is not set CONFIG_TCP_CONG_ADVANCED=y # CONFIG_TCP_CONG_BIC is not set @@ -44,7 +39,8 @@ CONFIG_TCP_CONG_WESTWOOD=y CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_NAND_JZ4740=y +CONFIG_MTD_NAND_JZ4780=y +CONFIG_MTD_NAND_JZ4740_ECC=y CONFIG_MTD_UBI=y CONFIG_NETDEVICES=y # CONFIG_WLAN is not set @@ -66,18 +62,20 @@ CONFIG_SERIAL_8250_INGENIC=y CONFIG_SPI=y CONFIG_SPI_GPIO=y CONFIG_POWER_SUPPLY=y -CONFIG_BATTERY_JZ4740=y +CONFIG_BATTERY_INGENIC=y CONFIG_CHARGER_GPIO=y -# CONFIG_HWMON is not set +CONFIG_SENSORS_IIO_HWMON=y CONFIG_WATCHDOG=y CONFIG_JZ4740_WDT=y -CONFIG_MFD_JZ4740_ADC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_FB=y -CONFIG_FB_JZ4740=y -CONFIG_LCD_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +CONFIG_DRM=y +CONFIG_DRM_FBDEV_OVERALLOC=200 +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_INGENIC=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set # CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y @@ -92,13 +90,13 @@ CONFIG_SND=y # CONFIG_SND_SPI is not set # CONFIG_SND_MIPS is not set CONFIG_SND_SOC=y -CONFIG_SND_JZ4740_SOC=y -CONFIG_SND_JZ4740_SOC_QI_LB60=y -CONFIG_USB=y -CONFIG_USB_OTG_BLACKLIST_HUB=y +CONFIG_SND_JZ4740_SOC_I2S=y +CONFIG_SND_SOC_JZ4740_CODEC=y +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=y +CONFIG_SND_SIMPLE_CARD=y CONFIG_USB_MUSB_HDRC=y -CONFIG_USB_MUSB_GADGET=y CONFIG_USB_MUSB_JZ4740=y +CONFIG_USB_INVENTRA_DMA=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG=y @@ -109,11 +107,13 @@ CONFIG_MMC_JZ4740=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_JZ4740=y CONFIG_DMADEVICES=y -CONFIG_DMA_JZ4740=y +CONFIG_DMA_JZ4780=y +CONFIG_MEMORY=y +CONFIG_IIO=y +CONFIG_INGENIC_ADC=y CONFIG_PWM=y CONFIG_PWM_JZ4740=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y +CONFIG_EXT4_FS=y # CONFIG_DNOTIFY is not set CONFIG_VFAT_FS=y CONFIG_PROC_KCORE=y diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c index 429b7f8d2aeb..af44b35d79a1 100644 --- a/arch/mips/fw/arc/memory.c +++ b/arch/mips/fw/arc/memory.c @@ -27,6 +27,11 @@ #undef DEBUG +#define MAX_PROM_MEM 5 +static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata; +static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata; +static unsigned int nr_prom_mem __initdata; + /* * For ARC firmware memory functions the unit of meassuring memory is always * a 4k page of memory @@ -129,6 +134,7 @@ void __init prom_meminit(void) } #endif + nr_prom_mem = 0; p = PROM_NULL_MDESC; while ((p = ArcGetMemoryDescriptor(p))) { unsigned long base, size; @@ -139,6 +145,16 @@ void __init prom_meminit(void) type = prom_memtype_classify(p->type); add_memory_region(base, size, type); + + if (type == BOOT_MEM_ROM_DATA) { + if (nr_prom_mem >= 5) { + pr_err("Too many ROM DATA regions"); + continue; + } + prom_mem_base[nr_prom_mem] = base; + prom_mem_size[nr_prom_mem] = size; + nr_prom_mem++; + } } } @@ -150,12 +166,8 @@ void __init prom_free_prom_memory(void) if (prom_flags & PROM_FLAG_DONT_FREE_TEMP) return; - for (i = 0; i < boot_mem_map.nr_map; i++) { - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) - continue; - - addr = boot_mem_map.map[i].addr; + for (i = 0; i < nr_prom_mem; i++) { free_init_pages("prom memory", - addr, addr + boot_mem_map.map[i].size); + prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]); } } diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h index 4856adc8906e..59a48c60a065 100644 --- a/arch/mips/include/asm/addrspace.h +++ b/arch/mips/include/asm/addrspace.h @@ -135,18 +135,9 @@ */ #define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */ -#ifndef CONFIG_CPU_R8000 - -/* - * The R8000 doesn't have the 32-bit compat spaces so we don't define them - * in order to catch bugs in the source code. - */ - #define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000) #define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */ -#endif - #define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK) #define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE) diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 9a82dd11c0e9..bb8658cc7f12 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -68,7 +68,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \ "\t" __scbeqz " %0, 1b \n" \ " .set pop \n" \ : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -98,7 +98,7 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \ " .set pop \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -132,7 +132,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \ " move %0, %1 \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -193,6 +193,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) if (kernel_uses_llsc) { int temp; + loongson_llsc_mb(); __asm__ __volatile__( " .set push \n" " .set "MIPS_ISA_LEVEL" \n" @@ -200,16 +201,16 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) " .set pop \n" " subu %0, %1, %3 \n" " move %1, %0 \n" - " bltz %0, 1f \n" + " bltz %0, 2f \n" " .set push \n" " .set "MIPS_ISA_LEVEL" \n" " sc %1, %2 \n" "\t" __scbeqz " %1, 1b \n" - "1: \n" + "2: \n" " .set pop \n" : "=&r" (result), "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) - : "Ir" (i)); + : "Ir" (i) : __LLSC_CLOBBER); } else { unsigned long flags; @@ -269,7 +270,7 @@ static __inline__ void atomic64_##op(s64 i, atomic64_t * v) \ "\t" __scbeqz " %0, 1b \n" \ " .set pop \n" \ : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -299,7 +300,7 @@ static __inline__ s64 atomic64_##op##_return_relaxed(s64 i, atomic64_t * v) \ " .set pop \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ @@ -333,7 +334,7 @@ static __inline__ s64 atomic64_fetch_##op##_relaxed(s64 i, atomic64_t * v) \ " .set pop \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ + : "Ir" (i) : __LLSC_CLOBBER); \ } else { \ unsigned long flags; \ \ diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index b865e317a14f..9228f7386220 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h @@ -211,14 +211,22 @@ #define __smp_wmb() barrier() #endif +/* + * When LL/SC does imply order, it must also be a compiler barrier to avoid the + * compiler from reordering where the CPU will not. When it does not imply + * order, the compiler is also free to reorder across the LL/SC loop and + * ordering will be done by smp_llsc_mb() and friends. + */ #if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP) #define __WEAK_LLSC_MB " sync \n" +#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") +#define __LLSC_CLOBBER #else #define __WEAK_LLSC_MB " \n" +#define smp_llsc_mb() do { } while (0) +#define __LLSC_CLOBBER "memory" #endif -#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") - #ifdef CONFIG_CPU_CAVIUM_OCTEON #define smp_mb__before_llsc() smp_wmb() #define __smp_mb__before_llsc() __smp_wmb() @@ -238,36 +246,40 @@ /* * Some Loongson 3 CPUs have a bug wherein execution of a memory access (load, - * store or pref) in between an ll & sc can cause the sc instruction to + * store or prefetch) in between an LL & SC can cause the SC instruction to * erroneously succeed, breaking atomicity. Whilst it's unusual to write code * containing such sequences, this bug bites harder than we might otherwise * expect due to reordering & speculation: * - * 1) A memory access appearing prior to the ll in program order may actually - * be executed after the ll - this is the reordering case. + * 1) A memory access appearing prior to the LL in program order may actually + * be executed after the LL - this is the reordering case. * - * In order to avoid this we need to place a memory barrier (ie. a sync - * instruction) prior to every ll instruction, in between it & any earlier - * memory access instructions. Many of these cases are already covered by - * smp_mb__before_llsc() but for the remaining cases, typically ones in - * which multiple CPUs may operate on a memory location but ordering is not - * usually guaranteed, we use loongson_llsc_mb() below. + * In order to avoid this we need to place a memory barrier (ie. a SYNC + * instruction) prior to every LL instruction, in between it and any earlier + * memory access instructions. * * This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later. * - * 2) If a conditional branch exists between an ll & sc with a target outside - * of the ll-sc loop, for example an exit upon value mismatch in cmpxchg() + * 2) If a conditional branch exists between an LL & SC with a target outside + * of the LL-SC loop, for example an exit upon value mismatch in cmpxchg() * or similar, then misprediction of the branch may allow speculative - * execution of memory accesses from outside of the ll-sc loop. + * execution of memory accesses from outside of the LL-SC loop. * - * In order to avoid this we need a memory barrier (ie. a sync instruction) + * In order to avoid this we need a memory barrier (ie. a SYNC instruction) * at each affected branch target, for which we also use loongson_llsc_mb() * defined below. * * This case affects all current Loongson 3 CPUs. + * + * The above described cases cause an error in the cache coherence protocol; + * such that the Invalidate of a competing LL-SC goes 'missing' and SC + * erroneously observes its core still has Exclusive state and lets the SC + * proceed. + * + * Therefore the error only occurs on SMP systems. */ #ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */ -#define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") +#define loongson_llsc_mb() __asm__ __volatile__("sync" : : :"memory") #else #define loongson_llsc_mb() do { } while (0) #endif diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 9a466dde9b96..985d6a02f9ea 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -66,7 +66,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " beqzl %0, 1b \n" " .set pop \n" : "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*m) - : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)); + : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m) + : __LLSC_CLOBBER); #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { loongson_llsc_mb(); @@ -76,7 +77,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " " __INS "%0, %3, %2, 1 \n" " " __SC "%0, %1 \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (bit), "r" (~0)); + : "ir" (bit), "r" (~0) + : __LLSC_CLOBBER); } while (unlikely(!temp)); #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ } else if (kernel_uses_llsc) { @@ -90,7 +92,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (1UL << bit)); + : "ir" (1UL << bit) + : __LLSC_CLOBBER); } while (unlikely(!temp)); } else __mips_set_bit(nr, addr); @@ -122,7 +125,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " beqzl %0, 1b \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (~(1UL << bit))); + : "ir" (~(1UL << bit)) + : __LLSC_CLOBBER); #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { loongson_llsc_mb(); @@ -132,7 +136,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " " __INS "%0, $0, %2, 1 \n" " " __SC "%0, %1 \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (bit)); + : "ir" (bit) + : __LLSC_CLOBBER); } while (unlikely(!temp)); #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ } else if (kernel_uses_llsc) { @@ -146,7 +151,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (~(1UL << bit))); + : "ir" (~(1UL << bit)) + : __LLSC_CLOBBER); } while (unlikely(!temp)); } else __mips_clear_bit(nr, addr); @@ -192,7 +198,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) " beqzl %0, 1b \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (1UL << bit)); + : "ir" (1UL << bit) + : __LLSC_CLOBBER); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -207,7 +214,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) - : "ir" (1UL << bit)); + : "ir" (1UL << bit) + : __LLSC_CLOBBER); } while (unlikely(!temp)); } else __mips_change_bit(nr, addr); @@ -244,11 +252,12 @@ static inline int test_and_set_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; + loongson_llsc_mb(); do { __asm__ __volatile__( " .set push \n" @@ -259,7 +268,7 @@ static inline int test_and_set_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!res)); res = temp & (1UL << bit); @@ -300,11 +309,12 @@ static inline int test_and_set_bit_lock(unsigned long nr, " .set pop \n" : "=&r" (temp), "+m" (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; + loongson_llsc_mb(); do { __asm__ __volatile__( " .set push \n" @@ -315,7 +325,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!res)); res = temp & (1UL << bit); @@ -358,12 +368,13 @@ static inline int test_and_clear_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) } else if (kernel_uses_llsc && __builtin_constant_p(nr)) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; + loongson_llsc_mb(); do { __asm__ __volatile__( " " __LL "%0, %1 # test_and_clear_bit \n" @@ -372,13 +383,14 @@ static inline int test_and_clear_bit(unsigned long nr, " " __SC "%0, %1 \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "ir" (bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!temp)); #endif } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; + loongson_llsc_mb(); do { __asm__ __volatile__( " .set push \n" @@ -390,7 +402,7 @@ static inline int test_and_clear_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!res)); res = temp & (1UL << bit); @@ -433,11 +445,12 @@ static inline int test_and_change_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; + loongson_llsc_mb(); do { __asm__ __volatile__( " .set push \n" @@ -448,7 +461,7 @@ static inline int test_and_change_bit(unsigned long nr, " .set pop \n" : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) : "r" (1UL << bit) - : "memory"); + : __LLSC_CLOBBER); } while (unlikely(!res)); res = temp & (1UL << bit); diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 235bc2f52113..34d62229dea5 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -81,34 +81,19 @@ enum loongson_machine_type { #define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */ #define MACH_INGENIC_JZ4770 2 /* JZ4770 SOC */ #define MACH_INGENIC_JZ4780 3 /* JZ4780 SOC */ +#define MACH_INGENIC_X1000 4 /* X1000 SOC */ extern char *system_type; const char *get_system_type(void); extern unsigned long mips_machtype; -#define BOOT_MEM_MAP_MAX 32 #define BOOT_MEM_RAM 1 #define BOOT_MEM_ROM_DATA 2 #define BOOT_MEM_RESERVED 3 #define BOOT_MEM_INIT_RAM 4 #define BOOT_MEM_NOMAP 5 -/* - * A memory map that's built upon what was determined - * or specified on the command line. - */ -struct boot_mem_map { - int nr_map; - struct boot_mem_map_entry { - phys_addr_t addr; /* start of memory segment */ - phys_addr_t size; /* size of memory segment */ - long type; /* type of memory segment */ - } map[BOOT_MEM_MAP_MAX]; -}; - -extern struct boot_mem_map boot_mem_map; - extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type); extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max); diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index f345a873742d..79bf34efbc04 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h @@ -46,6 +46,7 @@ extern unsigned long __xchg_called_with_bad_pointer(void) __typeof(*(m)) __ret; \ \ if (kernel_uses_llsc) { \ + loongson_llsc_mb(); \ __asm__ __volatile__( \ " .set push \n" \ " .set noat \n" \ @@ -60,7 +61,7 @@ extern unsigned long __xchg_called_with_bad_pointer(void) " .set pop \n" \ : "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \ : GCC_OFF_SMALL_ASM() (*m), "Jr" (val) \ - : "memory"); \ + : __LLSC_CLOBBER); \ } else { \ unsigned long __flags; \ \ @@ -117,6 +118,7 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x, __typeof(*(m)) __ret; \ \ if (kernel_uses_llsc) { \ + loongson_llsc_mb(); \ __asm__ __volatile__( \ " .set push \n" \ " .set noat \n" \ @@ -132,8 +134,9 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x, " .set pop \n" \ "2: \n" \ : "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \ - : GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \ - : "memory"); \ + : GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \ + : __LLSC_CLOBBER); \ + loongson_llsc_mb(); \ } else { \ unsigned long __flags; \ \ @@ -229,6 +232,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr, */ local_irq_save(flags); + loongson_llsc_mb(); asm volatile( " .set push \n" " .set " MIPS_ISA_ARCH_LEVEL " \n" @@ -274,6 +278,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr, "r" (old), "r" (new) : "memory"); + loongson_llsc_mb(); local_irq_restore(flags); return ret; @@ -290,10 +295,13 @@ static inline unsigned long __cmpxchg64(volatile void *ptr, * will cause a build error unless cpu_has_64bits is a \ * compile-time constant 1. \ */ \ - if (cpu_has_64bits && kernel_uses_llsc) \ + if (cpu_has_64bits && kernel_uses_llsc) { \ + smp_mb__before_llsc(); \ __res = __cmpxchg64((ptr), __old, __new); \ - else \ + smp_llsc_mb(); \ + } else { \ __res = __cmpxchg64_unsupported(); \ + } \ \ __res; \ }) diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 6998a9796499..983a6a7f43a1 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -243,9 +243,6 @@ #ifndef cpu_has_pindexed_dcache #define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) #endif -#ifndef cpu_has_local_ebase -#define cpu_has_local_ebase 1 -#endif /* * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors @@ -397,6 +394,22 @@ #define cpu_has_dsp3 __ase(MIPS_ASE_DSP3) #endif +#ifndef cpu_has_loongson_mmi +#define cpu_has_loongson_mmi __ase(MIPS_ASE_LOONGSON_MMI) +#endif + +#ifndef cpu_has_loongson_cam +#define cpu_has_loongson_cam __ase(MIPS_ASE_LOONGSON_CAM) +#endif + +#ifndef cpu_has_loongson_ext +#define cpu_has_loongson_ext __ase(MIPS_ASE_LOONGSON_EXT) +#endif + +#ifndef cpu_has_loongson_ext2 +#define cpu_has_loongson_ext2 __ase(MIPS_ASE_LOONGSON_EXT2) +#endif + #ifndef cpu_has_mipsmt #define cpu_has_mipsmt __isa_lt_and_ase(6, MIPS_ASE_MIPSMT) #endif diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index a45af3de075d..7bbb66760a07 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -38,7 +38,7 @@ static inline int __pure __get_cpu_type(const int cpu_type) #if defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) || \ defined(CONFIG_SYS_HAS_CPU_MIPS32_R2) case CPU_4KEC: - case CPU_JZRISC: + case CPU_XBURST: #endif #ifdef CONFIG_SYS_HAS_CPU_MIPS32_R2 @@ -116,11 +116,6 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_VR4181A: #endif -#ifdef CONFIG_SYS_HAS_CPU_R4300 - case CPU_R4300: - case CPU_R4310: -#endif - #ifdef CONFIG_SYS_HAS_CPU_R4X00 case CPU_R4000PC: case CPU_R4000SC: @@ -143,10 +138,6 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_R5000: #endif -#ifdef CONFIG_SYS_HAS_CPU_R5432 - case CPU_R5432: -#endif - #ifdef CONFIG_SYS_HAS_CPU_R5500 case CPU_R5500: #endif @@ -155,10 +146,6 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_NEVADA: #endif -#ifdef CONFIG_SYS_HAS_CPU_R8000 - case CPU_R8000: -#endif - #ifdef CONFIG_SYS_HAS_CPU_R10000 case CPU_R10000: case CPU_R12000: diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 290369fa44a4..7fddcb8350c6 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -47,7 +47,7 @@ #define PRID_COMP_CAVIUM 0x0d0000 #define PRID_COMP_LOONGSON 0x140000 #define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */ -#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */ +#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775, X1000 */ #define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */ /* @@ -183,7 +183,7 @@ * These are the PRID's for when 23:16 == PRID_COMP_INGENIC_* */ -#define PRID_IMP_JZRISC 0x0200 +#define PRID_IMP_XBURST 0x0200 /* * These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC @@ -293,19 +293,14 @@ enum cpu_type_enum { /* * R4000 class processors */ - CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310, + CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650, - CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000, + CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R10000, CPU_R12000, CPU_R14000, CPU_R16000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000, CPU_SR71000, CPU_TX49XX, /* - * R8000 class processors - */ - CPU_R8000, - - /* * TX3900 class processors */ CPU_TX3912, CPU_TX3922, CPU_TX3927, @@ -315,7 +310,7 @@ enum cpu_type_enum { */ CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, - CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC, + CPU_BMIPS4380, CPU_BMIPS5000, CPU_XBURST, CPU_LOONGSON1, CPU_M14KC, CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K, CPU_M5150, CPU_I6400, CPU_P6600, CPU_M6250, @@ -433,5 +428,9 @@ enum cpu_type_enum { #define MIPS_ASE_MSA 0x00000100 /* MIPS SIMD Architecture */ #define MIPS_ASE_DSP3 0x00000200 /* Signal Processing ASE Rev 3*/ #define MIPS_ASE_MIPS16E2 0x00000400 /* MIPS16e2 */ +#define MIPS_ASE_LOONGSON_MMI 0x00000800 /* Loongson MultiMedia extensions Instructions */ +#define MIPS_ASE_LOONGSON_CAM 0x00001000 /* Loongson CAM */ +#define MIPS_ASE_LOONGSON_EXT 0x00002000 /* Loongson EXTensions */ +#define MIPS_ASE_LOONGSON_EXT2 0x00004000 /* Loongson EXTensions R2 */ #endif /* _ASM_CPU_H */ diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 97a280640daf..2b7b56736372 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -63,21 +63,11 @@ * instruction, so the lower 16 bits must be zero. Should be true on * on any sane architecture; generic code does not use this assumption. */ -extern const unsigned long mips_io_port_base; +extern unsigned long mips_io_port_base; -/* - * Gcc will generate code to load the value of mips_io_port_base after each - * function call which may be fairly wasteful in some cases. So we don't - * play quite by the book. We tell gcc mips_io_port_base is a long variable - * which solves the code generation issue. Now we need to violate the - * aliasing rules a little to make initialization possible and finally we - * will need the barrier() to fight side effects of the aliasing chat. - * This trickery will eventually collapse under gcc's optimizer. Oh well. - */ static inline void set_io_port_base(unsigned long base) { - * (unsigned long *) &mips_io_port_base = base; - barrier(); + mips_io_port_base = base; } /* @@ -262,11 +252,11 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, #define ioremap_uc ioremap_nocache /* - * ioremap_cachable - map bus memory into CPU space + * ioremap_cache - map bus memory into CPU space * @offset: bus address of the memory * @size: size of the resource to map * - * ioremap_nocache performs a platform specific sequence of operations to + * ioremap_cache performs a platform specific sequence of operations to * make bus memory CPU accessible via the readb/readw/readl/writeb/ * writew/writel functions and the other mmio helpers. The returned * address is not guaranteed to be usable directly as a virtual @@ -276,9 +266,8 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, * the CPU. Also enables full write-combining. Useful for some * memory-like regions on I/O busses. */ -#define ioremap_cachable(offset, size) \ +#define ioremap_cache(offset, size) \ __ioremap_mode((offset), (size), _page_cachable_default) -#define ioremap_cache ioremap_cachable /* * ioremap_wc - map bus memory into CPU space diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h index 0ef8893e07f8..f879be3e8099 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h @@ -98,6 +98,7 @@ enum bcm47xx_board { BCM47XX_BOARD_MOTOROLA_WR850GP, BCM47XX_BOARD_MOTOROLA_WR850GV2V3, + BCM47XX_BOARD_NETGEAR_R6200_V1, BCM47XX_BOARD_NETGEAR_WGR614V8, BCM47XX_BOARD_NETGEAR_WGR614V9, BCM47XX_BOARD_NETGEAR_WGR614_V10, diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index a4f798629c3d..513270c8adb9 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h @@ -45,7 +45,6 @@ #define cpu_has_ic_fills_f_dc 0 #define cpu_has_64bits 1 #define cpu_has_octeon_cache 1 -#define cpu_has_saa octeon_has_saa() #define cpu_has_mips32r1 1 #define cpu_has_mips32r2 1 #define cpu_has_mips64r1 1 @@ -60,7 +59,6 @@ #define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON) -#define ARCH_HAS_IRQ_PER_CPU 1 #define ARCH_HAS_SPINLOCK_PREFETCH 1 #define spin_lock_prefetch(x) prefetch(x) #define PREFETCH_STRIDE 128 @@ -73,13 +71,6 @@ #define ARCH_HAS_USABLE_BUILTIN_POPCOUNT 1 #endif -static inline int octeon_has_saa(void) -{ - int id; - asm volatile ("mfc0 %0, $15,0" : "=r" (id)); - return id >= 0x000d0300; -} - /* * The last 256MB are reserved for device to device mappings and the * BAR1 hole. diff --git a/arch/mips/include/asm/mach-cavium-octeon/war.h b/arch/mips/include/asm/mach-cavium-octeon/war.h index 35c80be92207..2421411b7636 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/war.h +++ b/arch/mips/include/asm/mach-cavium-octeon/war.h @@ -12,7 +12,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h index 1c11310bc8ad..00beb69bfab9 100644 --- a/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h @@ -32,7 +32,6 @@ #define cpu_has_vtag_icache 0 #define cpu_has_ic_fills_f_dc 0 #define cpu_has_pindexed_dcache 0 -#define cpu_has_local_ebase 0 #define cpu_icache_snoops_remote_store 1 #define cpu_has_mips_4 0 #define cpu_has_mips_5 0 diff --git a/arch/mips/include/asm/mach-generic/war.h b/arch/mips/include/asm/mach-generic/war.h index a1bc2e71f983..f0f4a35d0870 100644 --- a/arch/mips/include/asm/mach-generic/war.h +++ b/arch/mips/include/asm/mach-generic/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mach-ip22/war.h b/arch/mips/include/asm/mach-ip22/war.h index fba640517f4f..b48eb4ac362d 100644 --- a/arch/mips/include/asm/mach-ip22/war.h +++ b/arch/mips/include/asm/mach-ip22/war.h @@ -15,7 +15,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 1 #define R4600_V1_HIT_CACHEOP_WAR 1 #define R4600_V2_HIT_CACHEOP_WAR 1 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mach-ip27/war.h b/arch/mips/include/asm/mach-ip27/war.h index 4ee0e4bdf4fb..ef3efce0094a 100644 --- a/arch/mips/include/asm/mach-ip27/war.h +++ b/arch/mips/include/asm/mach-ip27/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mach-ip28/war.h b/arch/mips/include/asm/mach-ip28/war.h index 4821c7b7a38c..61cd67354829 100644 --- a/arch/mips/include/asm/mach-ip28/war.h +++ b/arch/mips/include/asm/mach-ip28/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mach-ip32/war.h b/arch/mips/include/asm/mach-ip32/war.h index 9807ecda5a88..e77b9d1b6c96 100644 --- a/arch/mips/include/asm/mach-ip32/war.h +++ b/arch/mips/include/asm/mach-ip32/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h deleted file mode 100644 index 2092a3597734..000000000000 --- a/arch/mips/include/asm/mach-jz4740/gpio.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - * JZ4740 GPIO pin definitions - */ - -#ifndef _JZ_GPIO_H -#define _JZ_GPIO_H - -#define JZ_GPIO_PORTA(x) ((x) + 32 * 0) -#define JZ_GPIO_PORTB(x) ((x) + 32 * 1) -#define JZ_GPIO_PORTC(x) ((x) + 32 * 2) -#define JZ_GPIO_PORTD(x) ((x) + 32 * 3) - -#endif diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_fb.h b/arch/mips/include/asm/mach-jz4740/jz4740_fb.h deleted file mode 100644 index e84a48f73285..000000000000 --- a/arch/mips/include/asm/mach-jz4740/jz4740_fb.h +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - */ - -#ifndef __ASM_MACH_JZ4740_JZ4740_FB_H__ -#define __ASM_MACH_JZ4740_JZ4740_FB_H__ - -#include <linux/fb.h> - -enum jz4740_fb_lcd_type { - JZ_LCD_TYPE_GENERIC_16_BIT = 0, - JZ_LCD_TYPE_GENERIC_18_BIT = 0 | (1 << 4), - JZ_LCD_TYPE_SPECIAL_TFT_1 = 1, - JZ_LCD_TYPE_SPECIAL_TFT_2 = 2, - JZ_LCD_TYPE_SPECIAL_TFT_3 = 3, - JZ_LCD_TYPE_NON_INTERLACED_CCIR656 = 5, - JZ_LCD_TYPE_INTERLACED_CCIR656 = 7, - JZ_LCD_TYPE_SINGLE_COLOR_STN = 8, - JZ_LCD_TYPE_SINGLE_MONOCHROME_STN = 9, - JZ_LCD_TYPE_DUAL_COLOR_STN = 10, - JZ_LCD_TYPE_DUAL_MONOCHROME_STN = 11, - JZ_LCD_TYPE_8BIT_SERIAL = 12, -}; - -#define JZ4740_FB_SPECIAL_TFT_CONFIG(start, stop) (((start) << 16) | (stop)) - -/* -* width: width of the lcd display in mm -* height: height of the lcd display in mm -* num_modes: size of modes -* modes: list of valid video modes -* bpp: bits per pixel for the lcd -* lcd_type: lcd type -*/ - -struct jz4740_fb_platform_data { - unsigned int width; - unsigned int height; - - size_t num_modes; - struct fb_videomode *modes; - - unsigned int bpp; - enum jz4740_fb_lcd_type lcd_type; - - struct { - uint32_t spl; - uint32_t cls; - uint32_t ps; - uint32_t rev; - } special_tft_config; - - unsigned pixclk_falling_edge:1; - unsigned date_enable_active_low:1; -}; - -#endif diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h b/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h deleted file mode 100644 index 9a7de47c7c79..000000000000 --- a/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __LINUX_MMC_JZ4740_MMC -#define __LINUX_MMC_JZ4740_MMC - -struct jz4740_mmc_platform_data { - unsigned card_detect_active_low:1; - unsigned read_only_active_low:1; - - unsigned data_1bit:1; -}; - -#endif diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h deleted file mode 100644 index 241270d3ea14..000000000000 --- a/arch/mips/include/asm/mach-jz4740/platform.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> - * JZ4740 platform device definitions - */ - - -#ifndef __JZ4740_PLATFORM_H -#define __JZ4740_PLATFORM_H - -#include <linux/platform_device.h> - -extern struct platform_device jz4740_udc_device; -extern struct platform_device jz4740_udc_xceiv_device; -extern struct platform_device jz4740_mmc_device; -extern struct platform_device jz4740_i2c_device; -extern struct platform_device jz4740_nand_device; -extern struct platform_device jz4740_framebuffer_device; -extern struct platform_device jz4740_i2s_device; -extern struct platform_device jz4740_pcm_device; -extern struct platform_device jz4740_codec_device; -extern struct platform_device jz4740_adc_device; -extern struct platform_device jz4740_pwm_device; -extern struct platform_device jz4740_dma_device; - -#endif diff --git a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h index 581915ce231c..4aca25f2ff06 100644 --- a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h @@ -43,7 +43,6 @@ #define cpu_has_vint 0 #define cpu_has_vtag_icache 0 #define cpu_has_watch 1 -#define cpu_has_local_ebase 0 #ifdef CONFIG_CPU_LOONGSON3 #define cpu_has_wsbh 1 diff --git a/arch/mips/include/asm/mach-malta/war.h b/arch/mips/include/asm/mach-malta/war.h index d068fc411f47..d62d2ffe515e 100644 --- a/arch/mips/include/asm/mach-malta/war.h +++ b/arch/mips/include/asm/mach-malta/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 1 diff --git a/arch/mips/include/asm/mach-pmcs-msp71xx/war.h b/arch/mips/include/asm/mach-pmcs-msp71xx/war.h index a60bf9dd14ae..31c546f58bb5 100644 --- a/arch/mips/include/asm/mach-pmcs-msp71xx/war.h +++ b/arch/mips/include/asm/mach-pmcs-msp71xx/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mach-rc32434/war.h b/arch/mips/include/asm/mach-rc32434/war.h index 1bfd489a3708..af430d26f713 100644 --- a/arch/mips/include/asm/mach-rc32434/war.h +++ b/arch/mips/include/asm/mach-rc32434/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 1 diff --git a/arch/mips/include/asm/mach-rm/war.h b/arch/mips/include/asm/mach-rm/war.h index a3dde98549bb..eca16d167c2f 100644 --- a/arch/mips/include/asm/mach-rm/war.h +++ b/arch/mips/include/asm/mach-rm/war.h @@ -15,7 +15,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 1 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h index 520f8fc2c806..4755b6116807 100644 --- a/arch/mips/include/asm/mach-sibyte/war.h +++ b/arch/mips/include/asm/mach-sibyte/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #if defined(CONFIG_SB1_PASS_2_WORKAROUNDS) diff --git a/arch/mips/include/asm/mach-tx49xx/war.h b/arch/mips/include/asm/mach-tx49xx/war.h index a8e2c586a18c..445abb4eb769 100644 --- a/arch/mips/include/asm/mach-tx49xx/war.h +++ b/arch/mips/include/asm/mach-tx49xx/war.h @@ -11,7 +11,6 @@ #define R4600_V1_INDEX_ICACHEOP_WAR 0 #define R4600_V1_HIT_CACHEOP_WAR 0 #define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 1e6966e8527e..bdbdc19a2b8f 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -689,6 +689,9 @@ #define MIPS_CONF7_IAR (_ULCAST_(1) << 10) #define MIPS_CONF7_AR (_ULCAST_(1) << 16) +/* Ingenic Config7 bits */ +#define MIPS_CONF7_BTB_LOOP_EN (_ULCAST_(1) << 4) + /* Config7 Bits specific to MIPS Technologies. */ /* Performance counters implemented Per TC */ @@ -2813,6 +2816,7 @@ __BUILD_SET_C0(status) __BUILD_SET_C0(cause) __BUILD_SET_C0(config) __BUILD_SET_C0(config5) +__BUILD_SET_C0(config7) __BUILD_SET_C0(intcontrol) __BUILD_SET_C0(intctl) __BUILD_SET_C0(srsmap) diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index 6dc0b21b8acd..ed70994fbbec 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -103,22 +103,16 @@ search_module_dbetables(unsigned long addr) #define MODULE_PROC_FAMILY "TX39XX " #elif defined CONFIG_CPU_VR41XX #define MODULE_PROC_FAMILY "VR41XX " -#elif defined CONFIG_CPU_R4300 -#define MODULE_PROC_FAMILY "R4300 " #elif defined CONFIG_CPU_R4X00 #define MODULE_PROC_FAMILY "R4X00 " #elif defined CONFIG_CPU_TX49XX #define MODULE_PROC_FAMILY "TX49XX " #elif defined CONFIG_CPU_R5000 #define MODULE_PROC_FAMILY "R5000 " -#elif defined CONFIG_CPU_R5432 -#define MODULE_PROC_FAMILY "R5432 " #elif defined CONFIG_CPU_R5500 #define MODULE_PROC_FAMILY "R5500 " #elif defined CONFIG_CPU_NEVADA #define MODULE_PROC_FAMILY "NEVADA " -#elif defined CONFIG_CPU_R8000 -#define MODULE_PROC_FAMILY "R8000 " #elif defined CONFIG_CPU_R10000 #define MODULE_PROC_FAMILY "R10000 " #elif defined CONFIG_CPU_RM7000 diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h index 60481502826a..a2e2876357ce 100644 --- a/arch/mips/include/asm/octeon/octeon.h +++ b/arch/mips/include/asm/octeon/octeon.h @@ -51,7 +51,7 @@ extern void octeon_setup_delays(void); extern void octeon_io_clk_delay(unsigned long); #define OCTEON_ARGV_MAX_ARGS 64 -#define OCTOEN_SERIAL_LEN 20 +#define OCTEON_SERIAL_LEN 20 struct octeon_boot_descriptor { #ifdef __BIG_ENDIAN_BITFIELD @@ -102,7 +102,7 @@ struct octeon_boot_descriptor { uint16_t chip_type; uint8_t chip_rev_major; uint8_t chip_rev_minor; - char board_serial_number[OCTOEN_SERIAL_LEN]; + char board_serial_number[OCTEON_SERIAL_LEN]; uint8_t mac_addr_base[6]; uint8_t mac_addr_count; uint64_t cvmx_desc_vaddr; diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index 74afe8c76bdd..ba967148b016 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h @@ -23,6 +23,24 @@ #include <asm/highmem.h> #endif +/* + * Regarding 32-bit MIPS huge page support (and the tradeoff it entails): + * + * We use the same huge page sizes as 64-bit MIPS. Assuming a 4KB page size, + * our 2-level table layout would normally have a PGD entry cover a contiguous + * 4MB virtual address region (pointing to a 4KB PTE page of 1,024 32-bit pte_t + * pointers, each pointing to a 4KB physical page). The problem is that 4MB, + * spanning both halves of a TLB EntryLo0,1 pair, requires 2MB hardware page + * support, not one of the standard supported sizes (1MB,4MB,16MB,...). + * To correct for this, when huge pages are enabled, we halve the number of + * pointers a PTE page holds, making its last half go to waste. Correspondingly, + * we double the number of PGD pages. Overall, page table memory overhead + * increases to match 64-bit MIPS, but PTE lookups remain CPU cache-friendly. + * + * NOTE: We don't yet support huge pages if extended-addressing is enabled + * (i.e. EVA, XPA, 36-bit Alchemy/Netlogic). + */ + extern int temp_tlb_entry; /* @@ -44,7 +62,12 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, */ /* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2) +#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) +# define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2 - 1) +#else +# define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2) +#endif + #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -52,14 +75,23 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, * Entries per page directory level: we use two-level, so * we don't really have any PUD/PMD directory physically. */ -#define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2) +#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) +# define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2 + 1) +#else +# define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2) +#endif + #define PGD_ORDER (__PGD_ORDER >= 0 ? __PGD_ORDER : 0) #define PUD_ORDER aieeee_attempt_to_allocate_pud -#define PMD_ORDER 1 +#define PMD_ORDER aieeee_attempt_to_allocate_pmd #define PTE_ORDER 0 #define PTRS_PER_PGD (USER_PTRS_PER_PGD * 2) -#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) +#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) +# define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t) / 2) +#else +# define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) +#endif #define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE) #define FIRST_USER_ADDRESS 0UL @@ -87,7 +119,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, extern void load_pgd(unsigned long pg_dir); -extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)]; +extern pte_t invalid_pte_table[PTRS_PER_PTE]; /* * Empty pgd/pmd entries point to the invalid_pte_table. @@ -97,7 +129,19 @@ static inline int pmd_none(pmd_t pmd) return pmd_val(pmd) == (unsigned long) invalid_pte_table; } -#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK) +static inline int pmd_bad(pmd_t pmd) +{ +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT + /* pmd_huge(pmd) but inline */ + if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) + return 0; +#endif + + if (unlikely(pmd_val(pmd) & ~PAGE_MASK)) + return 1; + + return 0; +} static inline int pmd_present(pmd_t pmd) { @@ -146,6 +190,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) #else #define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) #define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) __pmd(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) #endif #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ @@ -159,6 +204,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) #define pgd_offset_k(address) pgd_offset(&init_mm, address) #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) +#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) /* to find an entry in a page-table-directory */ #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) @@ -175,7 +221,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) #define pte_unmap(pte) ((void)(pte)) -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) +#if defined(CONFIG_CPU_R3K_TLB) /* Swap entries must have VALID bit cleared. */ #define __swp_type(x) (((x).val >> 10) & 0x1f) @@ -220,6 +266,6 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ -#endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */ +#endif /* defined(CONFIG_CPU_R3K_TLB) */ #endif /* _ASM_PGTABLE_32_H */ diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index f88a48cd68b2..4da79b85c179 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -52,6 +52,9 @@ enum pgtable_bits { _PAGE_WRITE_SHIFT, _PAGE_ACCESSED_SHIFT, _PAGE_MODIFIED_SHIFT, +#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) + _PAGE_SPECIAL_SHIFT, +#endif }; /* @@ -78,9 +81,12 @@ enum pgtable_bits { _PAGE_WRITE_SHIFT, _PAGE_ACCESSED_SHIFT, _PAGE_MODIFIED_SHIFT, +#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) + _PAGE_SPECIAL_SHIFT, +#endif }; -#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) +#elif defined(CONFIG_CPU_R3K_TLB) /* Page table bits used for r3k systems */ enum pgtable_bits { @@ -90,6 +96,9 @@ enum pgtable_bits { _PAGE_WRITE_SHIFT, _PAGE_ACCESSED_SHIFT, _PAGE_MODIFIED_SHIFT, +#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) + _PAGE_SPECIAL_SHIFT, +#endif /* Used by TLB hardware (placed in EntryLo) */ _PAGE_GLOBAL_SHIFT = 8, @@ -110,9 +119,12 @@ enum pgtable_bits { _PAGE_WRITE_SHIFT, _PAGE_ACCESSED_SHIFT, _PAGE_MODIFIED_SHIFT, -#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) +#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) _PAGE_HUGE_SHIFT, #endif +#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) + _PAGE_SPECIAL_SHIFT, +#endif /* Used by TLB hardware (placed in EntryLo*) */ #if defined(CONFIG_CPU_HAS_RIXI) @@ -132,9 +144,14 @@ enum pgtable_bits { #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) -#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) +#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) # define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) #endif +#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) +# define _PAGE_SPECIAL (1 << _PAGE_SPECIAL_SHIFT) +#else +# define _PAGE_SPECIAL 0 +#endif /* Used by TLB hardware (placed in EntryLo*) */ #if defined(CONFIG_XPA) @@ -146,7 +163,7 @@ enum pgtable_bits { #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) +#if defined(CONFIG_CPU_R3K_TLB) # define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT) # define _CACHE_MASK _CACHE_UNCACHED # define _PFN_SHIFT PAGE_SHIFT @@ -204,7 +221,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) /* * Cache attributes */ -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) +#if defined(CONFIG_CPU_R3K_TLB) #define _CACHE_CACHABLE_NONCOHERENT 0 #define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED @@ -216,13 +233,6 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) #define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT) -#elif defined(CONFIG_CPU_LOONGSON3) - -/* Using COHERENT flag for NONCOHERENT doesn't hurt. */ - -#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */ -#define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */ - #elif defined(CONFIG_MACH_INGENIC) /* Ingenic uses the WA bit to achieve write-combine memory writes */ diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 7d27194e3b45..4dca733d5076 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -199,7 +199,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt static inline void set_pte(pte_t *ptep, pte_t pteval) { *ptep = pteval; -#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) +#if !defined(CONFIG_CPU_R3K_TLB) if (pte_val(pteval) & _PAGE_GLOBAL) { pte_t *buddy = ptep_buddy(ptep); /* @@ -218,7 +218,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { htw_stop(); -#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) +#if !defined(CONFIG_CPU_R3K_TLB) /* Preserve global status for the pair */ if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL) set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL)); @@ -277,6 +277,7 @@ extern pgd_t swapper_pg_dir[]; static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } +static inline int pte_special(pte_t pte) { return pte.pte_low & _PAGE_SPECIAL; } static inline pte_t pte_wrprotect(pte_t pte) { @@ -337,10 +338,17 @@ static inline pte_t pte_mkyoung(pte_t pte) } return pte; } + +static inline pte_t pte_mkspecial(pte_t pte) +{ + pte.pte_low |= _PAGE_SPECIAL; + return pte; +} #else static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } static inline pte_t pte_wrprotect(pte_t pte) { @@ -384,6 +392,12 @@ static inline pte_t pte_mkyoung(pte_t pte) return pte; } +static inline pte_t pte_mkspecial(pte_t pte) +{ + pte_val(pte) |= _PAGE_SPECIAL; + return pte; +} + #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_HUGE; } @@ -394,8 +408,6 @@ static inline pte_t pte_mkhuge(pte_t pte) } #endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */ #endif -static inline int pte_special(pte_t pte) { return 0; } -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } /* * Macro to make mark a page protection value as "uncacheable". Note diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index 83bb439597d8..25fa651c937d 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -54,7 +54,7 @@ static inline void mips_syscall_update_nr(struct task_struct *task, task_thread_info(task)->syscall = regs->regs[2]; } -static inline unsigned long mips_get_syscall_arg(unsigned long *arg, +static inline void mips_get_syscall_arg(unsigned long *arg, struct task_struct *task, struct pt_regs *regs, unsigned int n) { unsigned long usp __maybe_unused = regs->regs[29]; @@ -63,23 +63,24 @@ static inline unsigned long mips_get_syscall_arg(unsigned long *arg, case 0: case 1: case 2: case 3: *arg = regs->regs[4 + n]; - return 0; + return; #ifdef CONFIG_32BIT case 4: case 5: case 6: case 7: - return get_user(*arg, (int *)usp + n); + get_user(*arg, (int *)usp + n); + return; #endif #ifdef CONFIG_64BIT case 4: case 5: case 6: case 7: #ifdef CONFIG_MIPS32_O32 if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) - return get_user(*arg, (int *)usp + n); + get_user(*arg, (int *)usp + n); else #endif *arg = regs->regs[4 + n]; - return 0; + return; #endif default: @@ -126,21 +127,13 @@ static inline void syscall_get_arguments(struct task_struct *task, { unsigned int i = 0; unsigned int n = 6; - int ret; /* O32 ABI syscall() */ if (mips_syscall_is_indirect(task, regs)) i++; while (n--) - ret |= mips_get_syscall_arg(args++, task, regs, i++); - - /* - * No way to communicate an error because this is a void function. - */ -#if 0 - return ret; -#endif + mips_get_syscall_arg(args++, task, regs, i++); } extern const unsigned long sys_call_table[]; diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h index a013fa4a3682..cc7b516129a8 100644 --- a/arch/mips/include/asm/vdso.h +++ b/arch/mips/include/asm/vdso.h @@ -8,6 +8,7 @@ #define __ASM_VDSO_H #include <linux/mm_types.h> +#include <vdso/datapage.h> #include <asm/barrier.h> @@ -49,84 +50,9 @@ extern struct mips_vdso_image vdso_image_o32; extern struct mips_vdso_image vdso_image_n32; #endif -/** - * union mips_vdso_data - Data provided by the kernel for the VDSO. - * @xtime_sec: Current real time (seconds part). - * @xtime_nsec: Current real time (nanoseconds part, shifted). - * @wall_to_mono_sec: Wall-to-monotonic offset (seconds part). - * @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part). - * @seq_count: Counter to synchronise updates (odd = updating). - * @cs_shift: Clocksource shift value. - * @clock_mode: Clocksource to use for time functions. - * @cs_mult: Clocksource multiplier value. - * @cs_cycle_last: Clock cycle value at last update. - * @cs_mask: Clocksource mask value. - * @tz_minuteswest: Minutes west of Greenwich (from timezone). - * @tz_dsttime: Type of DST correction (from timezone). - * - * This structure contains data needed by functions within the VDSO. It is - * populated by the kernel and mapped read-only into user memory. The time - * fields are mirrors of internal data from the timekeeping infrastructure. - * - * Note: Care should be taken when modifying as the layout must remain the same - * for both 64- and 32-bit (for 32-bit userland on 64-bit kernel). - */ union mips_vdso_data { - struct { - u64 xtime_sec; - u64 xtime_nsec; - u64 wall_to_mono_sec; - u64 wall_to_mono_nsec; - u32 seq_count; - u32 cs_shift; - u8 clock_mode; - u32 cs_mult; - u64 cs_cycle_last; - u64 cs_mask; - s32 tz_minuteswest; - s32 tz_dsttime; - }; - + struct vdso_data data[CS_BASES]; u8 page[PAGE_SIZE]; }; -static inline u32 vdso_data_read_begin(const union mips_vdso_data *data) -{ - u32 seq; - - while (true) { - seq = READ_ONCE(data->seq_count); - if (likely(!(seq & 1))) { - /* Paired with smp_wmb() in vdso_data_write_*(). */ - smp_rmb(); - return seq; - } - - cpu_relax(); - } -} - -static inline bool vdso_data_read_retry(const union mips_vdso_data *data, - u32 start_seq) -{ - /* Paired with smp_wmb() in vdso_data_write_*(). */ - smp_rmb(); - return unlikely(data->seq_count != start_seq); -} - -static inline void vdso_data_write_begin(union mips_vdso_data *data) -{ - ++data->seq_count; - - /* Ensure sequence update is written before other data page values. */ - smp_wmb(); -} - -static inline void vdso_data_write_end(union mips_vdso_data *data) -{ - /* Ensure data values are written before updating sequence again. */ - smp_wmb(); - ++data->seq_count; -} - #endif /* __ASM_VDSO_H */ diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h new file mode 100644 index 000000000000..e78462e8ca2e --- /dev/null +++ b/arch/mips/include/asm/vdso/gettimeofday.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2018 ARM Limited + * Copyright (C) 2015 Imagination Technologies + * Author: Alex Smith <alex.smith@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __ASM_VDSO_GETTIMEOFDAY_H +#define __ASM_VDSO_GETTIMEOFDAY_H + +#ifndef __ASSEMBLY__ + +#include <linux/compiler.h> +#include <linux/time.h> + +#include <asm/vdso/vdso.h> +#include <asm/clocksource.h> +#include <asm/io.h> +#include <asm/unistd.h> +#include <asm/vdso.h> + +#define VDSO_HAS_CLOCK_GETRES 1 + +#ifdef CONFIG_MIPS_CLOCK_VSYSCALL + +static __always_inline long gettimeofday_fallback( + struct __kernel_old_timeval *_tv, + struct timezone *_tz) +{ + register struct timezone *tz asm("a1") = _tz; + register struct __kernel_old_timeval *tv asm("a0") = _tv; + register long ret asm("v0"); + register long nr asm("v0") = __NR_gettimeofday; + register long error asm("a3"); + + asm volatile( + " syscall\n" + : "=r" (ret), "=r" (error) + : "r" (tv), "r" (tz), "r" (nr) + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + + return error ? -ret : ret; +} + +#else + +static __always_inline long gettimeofday_fallback( + struct __kernel_old_timeval *_tv, + struct timezone *_tz) +{ + return -1; +} + +#endif + +static __always_inline long clock_gettime_fallback( + clockid_t _clkid, + struct __kernel_timespec *_ts) +{ + register struct __kernel_timespec *ts asm("a1") = _ts; + register clockid_t clkid asm("a0") = _clkid; + register long ret asm("v0"); +#if _MIPS_SIM == _MIPS_SIM_ABI64 + register long nr asm("v0") = __NR_clock_gettime; +#else + register long nr asm("v0") = __NR_clock_gettime64; +#endif + register long error asm("a3"); + + asm volatile( + " syscall\n" + : "=r" (ret), "=r" (error) + : "r" (clkid), "r" (ts), "r" (nr) + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + + return error ? -ret : ret; +} + +static __always_inline int clock_getres_fallback( + clockid_t _clkid, + struct __kernel_timespec *_ts) +{ + register struct __kernel_timespec *ts asm("a1") = _ts; + register clockid_t clkid asm("a0") = _clkid; + register long ret asm("v0"); +#if _MIPS_SIM == _MIPS_SIM_ABI64 + register long nr asm("v0") = __NR_clock_getres; +#else + register long nr asm("v0") = __NR_clock_getres_time64; +#endif + register long error asm("a3"); + + asm volatile( + " syscall\n" + : "=r" (ret), "=r" (error) + : "r" (clkid), "r" (ts), "r" (nr) + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + + return error ? -ret : ret; +} + +#if _MIPS_SIM != _MIPS_SIM_ABI64 + +#define VDSO_HAS_32BIT_FALLBACK 1 + +static __always_inline long clock_gettime32_fallback( + clockid_t _clkid, + struct old_timespec32 *_ts) +{ + register struct old_timespec32 *ts asm("a1") = _ts; + register clockid_t clkid asm("a0") = _clkid; + register long ret asm("v0"); + register long nr asm("v0") = __NR_clock_gettime; + register long error asm("a3"); + + asm volatile( + " syscall\n" + : "=r" (ret), "=r" (error) + : "r" (clkid), "r" (ts), "r" (nr) + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + + return error ? -ret : ret; +} + +static __always_inline int clock_getres32_fallback( + clockid_t _clkid, + struct old_timespec32 *_ts) +{ + register struct old_timespec32 *ts asm("a1") = _ts; + register clockid_t clkid asm("a0") = _clkid; + register long ret asm("v0"); + register long nr asm("v0") = __NR_clock_getres; + register long error asm("a3"); + + asm volatile( + " syscall\n" + : "=r" (ret), "=r" (error) + : "r" (clkid), "r" (ts), "r" (nr) + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + + return error ? -ret : ret; +} +#endif + +#ifdef CONFIG_CSRC_R4K + +static __always_inline u64 read_r4k_count(void) +{ + unsigned int count; + + __asm__ __volatile__( + " .set push\n" + " .set mips32r2\n" + " rdhwr %0, $2\n" + " .set pop\n" + : "=r" (count)); + + return count; +} + +#endif + +#ifdef CONFIG_CLKSRC_MIPS_GIC + +static __always_inline u64 read_gic_count(const struct vdso_data *data) +{ + void __iomem *gic = get_gic(data); + u32 hi, hi2, lo; + + do { + hi = __raw_readl(gic + sizeof(lo)); + lo = __raw_readl(gic); + hi2 = __raw_readl(gic + sizeof(lo)); + } while (hi2 != hi); + + return (((u64)hi) << 32) + lo; +} + +#endif + +static __always_inline u64 __arch_get_hw_counter(s32 clock_mode) +{ +#ifdef CONFIG_CLKSRC_MIPS_GIC + const struct vdso_data *data = get_vdso_data(); +#endif + u64 cycle_now; + + switch (clock_mode) { +#ifdef CONFIG_CSRC_R4K + case VDSO_CLOCK_R4K: + cycle_now = read_r4k_count(); + break; +#endif +#ifdef CONFIG_CLKSRC_MIPS_GIC + case VDSO_CLOCK_GIC: + cycle_now = read_gic_count(data); + break; +#endif + default: + cycle_now = 0; + break; + } + + return cycle_now; +} + +static __always_inline const struct vdso_data *__arch_get_vdso_data(void) +{ + return get_vdso_data(); +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_VDSO_GETTIMEOFDAY_H */ diff --git a/arch/mips/vdso/vdso.h b/arch/mips/include/asm/vdso/vdso.h index b65b169778e3..737ddfc3411c 100644 --- a/arch/mips/vdso/vdso.h +++ b/arch/mips/include/asm/vdso/vdso.h @@ -6,17 +6,6 @@ #include <asm/sgidefs.h> -#if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT) - -/* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */ -#define BUILD_VDSO32_64 -#undef CONFIG_64BIT -#define CONFIG_32BIT 1 -#ifndef __ASSEMBLY__ -#include <asm-generic/atomic64.h> -#endif -#endif - #ifndef __ASSEMBLY__ #include <asm/asm.h> @@ -69,14 +58,14 @@ static inline unsigned long get_vdso_base(void) return addr; } -static inline const union mips_vdso_data *get_vdso_data(void) +static inline const struct vdso_data *get_vdso_data(void) { - return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE); + return (const struct vdso_data *)(get_vdso_base() - PAGE_SIZE); } #ifdef CONFIG_CLKSRC_MIPS_GIC -static inline void __iomem *get_gic(const union mips_vdso_data *data) +static inline void __iomem *get_gic(const struct vdso_data *data) { return (void __iomem *)data - PAGE_SIZE; } diff --git a/arch/mips/include/asm/vdso/vsyscall.h b/arch/mips/include/asm/vdso/vsyscall.h new file mode 100644 index 000000000000..195314732233 --- /dev/null +++ b/arch/mips/include/asm/vdso/vsyscall.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_VDSO_VSYSCALL_H +#define __ASM_VDSO_VSYSCALL_H + +#ifndef __ASSEMBLY__ + +#include <linux/timekeeper_internal.h> +#include <vdso/datapage.h> + +extern struct vdso_data *vdso_data; + +/* + * Update the vDSO data page to keep in sync with kernel timekeeping. + */ +static __always_inline +struct vdso_data *__mips_get_k_vdso_data(void) +{ + return vdso_data; +} +#define __arch_get_k_vdso_data __mips_get_k_vdso_data + +static __always_inline +int __mips_get_clock_mode(struct timekeeper *tk) +{ + u32 clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode; + + return clock_mode; +} +#define __arch_get_clock_mode __mips_get_clock_mode + +static __always_inline +int __mips_use_vsyscall(struct vdso_data *vdata) +{ + return (vdata[CS_HRES_COARSE].clock_mode != VDSO_CLOCK_NONE); +} +#define __arch_use_vsyscall __mips_use_vsyscall + +/* The asm-generic header needs to be included after the definitions above */ +#include <asm-generic/vdso/vsyscall.h> + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_VDSO_VSYSCALL_H */ diff --git a/arch/mips/include/asm/war.h b/arch/mips/include/asm/war.h index 9344e247a6c8..1eedd596a064 100644 --- a/arch/mips/include/asm/war.h +++ b/arch/mips/include/asm/war.h @@ -129,19 +129,6 @@ #endif /* - * When an interrupt happens on a CP0 register read instruction, CPU may - * lock up or read corrupted values of CP0 registers after it enters - * the exception handler. - * - * This workaround makes sure that we read a "safe" CP0 register as the - * first thing in the exception handler, which breaks one of the - * pre-conditions for this problem. - */ -#ifndef R5432_CP0_INTERRUPT_WAR -#error Check setting of R5432_CP0_INTERRUPT_WAR for your platform -#endif - -/* * Workaround for the Sibyte M3 errata the text of which can be found at * * http://sibyte.broadcom.com/hw/bcm1250/docs/pass2errata.txt diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile index 88d6aa7d000b..6de14c0deb4e 100644 --- a/arch/mips/jz4740/Makefile +++ b/arch/mips/jz4740/Makefile @@ -5,15 +5,10 @@ # Object file lists. -obj-y += prom.o time.o reset.o setup.o \ - platform.o timer.o +obj-y += prom.o time.o reset.o setup.o timer.o CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt -# board specific support - -obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o - # PM support obj-$(CONFIG_PM) += pm.o diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c deleted file mode 100644 index 4a7a80c358c7..000000000000 --- a/arch/mips/jz4740/board-qi_lb60.c +++ /dev/null @@ -1,523 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * linux/arch/mips/jz4740/board-qi_lb60.c - * - * QI_LB60 board support - * - * Copyright (c) 2009 Qi Hardware inc., - * Author: Xiangfu Liu <xiangfu@qi-hardware.com> - * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de> - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/gpio.h> -#include <linux/gpio/machine.h> - -#include <linux/input.h> -#include <linux/gpio_keys.h> -#include <linux/input/matrix_keypad.h> -#include <linux/spi/spi.h> -#include <linux/spi/spi_gpio.h> -#include <linux/pinctrl/machine.h> -#include <linux/pinctrl/pinconf-generic.h> -#include <linux/power_supply.h> -#include <linux/power/jz4740-battery.h> -#include <linux/power/gpio-charger.h> -#include <linux/pwm.h> - -#include <linux/platform_data/jz4740/jz4740_nand.h> - -#include <asm/mach-jz4740/gpio.h> -#include <asm/mach-jz4740/jz4740_fb.h> -#include <asm/mach-jz4740/jz4740_mmc.h> - -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> - -#include <asm/mach-jz4740/platform.h> - -/* GPIOs */ -#define QI_LB60_GPIO_KEYOUT(x) (JZ_GPIO_PORTC(10) + (x)) -#define QI_LB60_GPIO_KEYIN(x) (JZ_GPIO_PORTD(18) + (x)) -#define QI_LB60_GPIO_KEYIN8 JZ_GPIO_PORTD(26) - -/* NAND */ - -/* Early prototypes of the QI LB60 had only 1GB of NAND. - * In order to support these devices as well the partition and ecc layout is - * initialized depending on the NAND size */ -static struct mtd_partition qi_lb60_partitions_1gb[] = { - { - .name = "NAND BOOT partition", - .offset = 0 * 0x100000, - .size = 4 * 0x100000, - }, - { - .name = "NAND KERNEL partition", - .offset = 4 * 0x100000, - .size = 4 * 0x100000, - }, - { - .name = "NAND ROOTFS partition", - .offset = 8 * 0x100000, - .size = (504 + 512) * 0x100000, - }, -}; - -static struct mtd_partition qi_lb60_partitions_2gb[] = { - { - .name = "NAND BOOT partition", - .offset = 0 * 0x100000, - .size = 4 * 0x100000, - }, - { - .name = "NAND KERNEL partition", - .offset = 4 * 0x100000, - .size = 4 * 0x100000, - }, - { - .name = "NAND ROOTFS partition", - .offset = 8 * 0x100000, - .size = (504 + 512 + 1024) * 0x100000, - }, -}; - -static int qi_lb60_ooblayout_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - if (section) - return -ERANGE; - - oobregion->length = 36; - oobregion->offset = 6; - - if (mtd->oobsize == 128) { - oobregion->length *= 2; - oobregion->offset *= 2; - } - - return 0; -} - -static int qi_lb60_ooblayout_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - int eccbytes = 36, eccoff = 6; - - if (section > 1) - return -ERANGE; - - if (mtd->oobsize == 128) { - eccbytes *= 2; - eccoff *= 2; - } - - if (!section) { - oobregion->offset = 2; - oobregion->length = eccoff - 2; - } else { - oobregion->offset = eccoff + eccbytes; - oobregion->length = mtd->oobsize - oobregion->offset; - } - - return 0; -} - -static const struct mtd_ooblayout_ops qi_lb60_ooblayout_ops = { - .ecc = qi_lb60_ooblayout_ecc, - .free = qi_lb60_ooblayout_free, -}; - -static void qi_lb60_nand_ident(struct platform_device *pdev, - struct mtd_info *mtd, struct mtd_partition **partitions, - int *num_partitions) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - - if (chip->page_shift == 12) { - *partitions = qi_lb60_partitions_2gb; - *num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb); - } else { - *partitions = qi_lb60_partitions_1gb; - *num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb); - } - - mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops); -} - -static struct jz_nand_platform_data qi_lb60_nand_pdata = { - .ident_callback = qi_lb60_nand_ident, - .banks = { 1 }, -}; - -static struct gpiod_lookup_table qi_lb60_nand_gpio_table = { - .dev_id = "jz4740-nand.0", - .table = { - GPIO_LOOKUP("GPIOC", 30, "busy", 0), - { }, - }, -}; - - -/* Keyboard*/ - -#define KEY_QI_QI KEY_F13 -#define KEY_QI_UPRED KEY_RIGHTALT -#define KEY_QI_VOLUP KEY_VOLUMEUP -#define KEY_QI_VOLDOWN KEY_VOLUMEDOWN -#define KEY_QI_FN KEY_LEFTCTRL - -static const uint32_t qi_lb60_keymap[] = { - KEY(0, 0, KEY_F1), /* S2 */ - KEY(0, 1, KEY_F2), /* S3 */ - KEY(0, 2, KEY_F3), /* S4 */ - KEY(0, 3, KEY_F4), /* S5 */ - KEY(0, 4, KEY_F5), /* S6 */ - KEY(0, 5, KEY_F6), /* S7 */ - KEY(0, 6, KEY_F7), /* S8 */ - - KEY(1, 0, KEY_Q), /* S10 */ - KEY(1, 1, KEY_W), /* S11 */ - KEY(1, 2, KEY_E), /* S12 */ - KEY(1, 3, KEY_R), /* S13 */ - KEY(1, 4, KEY_T), /* S14 */ - KEY(1, 5, KEY_Y), /* S15 */ - KEY(1, 6, KEY_U), /* S16 */ - KEY(1, 7, KEY_I), /* S17 */ - KEY(2, 0, KEY_A), /* S18 */ - KEY(2, 1, KEY_S), /* S19 */ - KEY(2, 2, KEY_D), /* S20 */ - KEY(2, 3, KEY_F), /* S21 */ - KEY(2, 4, KEY_G), /* S22 */ - KEY(2, 5, KEY_H), /* S23 */ - KEY(2, 6, KEY_J), /* S24 */ - KEY(2, 7, KEY_K), /* S25 */ - KEY(3, 0, KEY_ESC), /* S26 */ - KEY(3, 1, KEY_Z), /* S27 */ - KEY(3, 2, KEY_X), /* S28 */ - KEY(3, 3, KEY_C), /* S29 */ - KEY(3, 4, KEY_V), /* S30 */ - KEY(3, 5, KEY_B), /* S31 */ - KEY(3, 6, KEY_N), /* S32 */ - KEY(3, 7, KEY_M), /* S33 */ - KEY(4, 0, KEY_TAB), /* S34 */ - KEY(4, 1, KEY_CAPSLOCK), /* S35 */ - KEY(4, 2, KEY_BACKSLASH), /* S36 */ - KEY(4, 3, KEY_APOSTROPHE), /* S37 */ - KEY(4, 4, KEY_COMMA), /* S38 */ - KEY(4, 5, KEY_DOT), /* S39 */ - KEY(4, 6, KEY_SLASH), /* S40 */ - KEY(4, 7, KEY_UP), /* S41 */ - KEY(5, 0, KEY_O), /* S42 */ - KEY(5, 1, KEY_L), /* S43 */ - KEY(5, 2, KEY_EQUAL), /* S44 */ - KEY(5, 3, KEY_QI_UPRED), /* S45 */ - KEY(5, 4, KEY_SPACE), /* S46 */ - KEY(5, 5, KEY_QI_QI), /* S47 */ - KEY(5, 6, KEY_RIGHTCTRL), /* S48 */ - KEY(5, 7, KEY_LEFT), /* S49 */ - KEY(6, 0, KEY_F8), /* S50 */ - KEY(6, 1, KEY_P), /* S51 */ - KEY(6, 2, KEY_BACKSPACE),/* S52 */ - KEY(6, 3, KEY_ENTER), /* S53 */ - KEY(6, 4, KEY_QI_VOLUP), /* S54 */ - KEY(6, 5, KEY_QI_VOLDOWN), /* S55 */ - KEY(6, 6, KEY_DOWN), /* S56 */ - KEY(6, 7, KEY_RIGHT), /* S57 */ - - KEY(7, 0, KEY_LEFTSHIFT), /* S58 */ - KEY(7, 1, KEY_LEFTALT), /* S59 */ - KEY(7, 2, KEY_QI_FN), /* S60 */ -}; - -static const struct matrix_keymap_data qi_lb60_keymap_data = { - .keymap = qi_lb60_keymap, - .keymap_size = ARRAY_SIZE(qi_lb60_keymap), -}; - -static const unsigned int qi_lb60_keypad_cols[] = { - QI_LB60_GPIO_KEYOUT(0), - QI_LB60_GPIO_KEYOUT(1), - QI_LB60_GPIO_KEYOUT(2), - QI_LB60_GPIO_KEYOUT(3), - QI_LB60_GPIO_KEYOUT(4), - QI_LB60_GPIO_KEYOUT(5), - QI_LB60_GPIO_KEYOUT(6), - QI_LB60_GPIO_KEYOUT(7), -}; - -static const unsigned int qi_lb60_keypad_rows[] = { - QI_LB60_GPIO_KEYIN(0), - QI_LB60_GPIO_KEYIN(1), - QI_LB60_GPIO_KEYIN(2), - QI_LB60_GPIO_KEYIN(3), - QI_LB60_GPIO_KEYIN(4), - QI_LB60_GPIO_KEYIN(5), - QI_LB60_GPIO_KEYIN(6), - QI_LB60_GPIO_KEYIN8, -}; - -static struct matrix_keypad_platform_data qi_lb60_pdata = { - .keymap_data = &qi_lb60_keymap_data, - .col_gpios = qi_lb60_keypad_cols, - .row_gpios = qi_lb60_keypad_rows, - .num_col_gpios = ARRAY_SIZE(qi_lb60_keypad_cols), - .num_row_gpios = ARRAY_SIZE(qi_lb60_keypad_rows), - .col_scan_delay_us = 10, - .debounce_ms = 10, - .wakeup = 1, - .active_low = 1, -}; - -static struct platform_device qi_lb60_keypad = { - .name = "matrix-keypad", - .id = -1, - .dev = { - .platform_data = &qi_lb60_pdata, - }, -}; - -/* Display */ -static struct fb_videomode qi_lb60_video_modes[] = { - { - .name = "320x240", - .xres = 320, - .yres = 240, - .refresh = 30, - .left_margin = 140, - .right_margin = 273, - .upper_margin = 20, - .lower_margin = 2, - .hsync_len = 1, - .vsync_len = 1, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct jz4740_fb_platform_data qi_lb60_fb_pdata = { - .width = 60, - .height = 45, - .num_modes = ARRAY_SIZE(qi_lb60_video_modes), - .modes = qi_lb60_video_modes, - .bpp = 24, - .lcd_type = JZ_LCD_TYPE_8BIT_SERIAL, - .pixclk_falling_edge = 1, -}; - -struct spi_gpio_platform_data qi_lb60_spigpio_platform_data = { - .num_chipselect = 1, -}; - -static struct platform_device qi_lb60_spigpio_device = { - .name = "spi_gpio", - .id = 1, - .dev = { - .platform_data = &qi_lb60_spigpio_platform_data, - }, -}; - -static struct gpiod_lookup_table qi_lb60_spigpio_gpio_table = { - .dev_id = "spi_gpio", - .table = { - GPIO_LOOKUP("GPIOC", 23, - "sck", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("GPIOC", 22, - "mosi", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("GPIOC", 21, - "cs", GPIO_ACTIVE_HIGH), - { }, - }, -}; - -static struct spi_board_info qi_lb60_spi_board_info[] = { - { - .modalias = "ili8960", - .chip_select = 0, - .bus_num = 1, - .max_speed_hz = 30 * 1000, - .mode = SPI_3WIRE, - }, -}; - -/* Battery */ -static struct jz_battery_platform_data qi_lb60_battery_pdata = { - .gpio_charge = JZ_GPIO_PORTC(27), - .gpio_charge_active_low = 1, - .info = { - .name = "battery", - .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, - .voltage_max_design = 4200000, - .voltage_min_design = 3600000, - }, -}; - -/* GPIO Key: power */ -static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = { - [0] = { - .code = KEY_POWER, - .gpio = JZ_GPIO_PORTD(29), - .active_low = 1, - .desc = "Power", - .wakeup = 1, - }, -}; - -static struct gpio_keys_platform_data qi_lb60_gpio_keys_data = { - .nbuttons = ARRAY_SIZE(qi_lb60_gpio_keys_buttons), - .buttons = qi_lb60_gpio_keys_buttons, -}; - -static struct platform_device qi_lb60_gpio_keys = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &qi_lb60_gpio_keys_data, - } -}; - -static struct jz4740_mmc_platform_data qi_lb60_mmc_pdata = { - /* Intentionally left blank */ -}; - -static struct gpiod_lookup_table qi_lb60_mmc_gpio_table = { - .dev_id = "jz4740-mmc.0", - .table = { - GPIO_LOOKUP("GPIOD", 0, "cd", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("GPIOD", 2, "power", GPIO_ACTIVE_LOW), - { }, - }, -}; - -/* beeper */ -static struct pwm_lookup qi_lb60_pwm_lookup[] = { - PWM_LOOKUP("jz4740-pwm", 4, "pwm-beeper", NULL, 0, - PWM_POLARITY_NORMAL), -}; - -static struct platform_device qi_lb60_pwm_beeper = { - .name = "pwm-beeper", - .id = -1, -}; - -/* charger */ -static char *qi_lb60_batteries[] = { - "battery", -}; - -static struct gpio_charger_platform_data qi_lb60_charger_pdata = { - .name = "usb", - .type = POWER_SUPPLY_TYPE_USB, - .gpio = JZ_GPIO_PORTD(28), - .gpio_active_low = 1, - .supplied_to = qi_lb60_batteries, - .num_supplicants = ARRAY_SIZE(qi_lb60_batteries), -}; - -static struct platform_device qi_lb60_charger_device = { - .name = "gpio-charger", - .dev = { - .platform_data = &qi_lb60_charger_pdata, - }, -}; - -/* audio */ -static struct platform_device qi_lb60_audio_device = { - .name = "qi-lb60-audio", - .id = -1, -}; - -static struct gpiod_lookup_table qi_lb60_audio_gpio_table = { - .dev_id = "qi-lb60-audio", - .table = { - GPIO_LOOKUP("GPIOB", 29, "snd", 0), - GPIO_LOOKUP("GPIOD", 4, "amp", 0), - { }, - }, -}; - -static struct platform_device *jz_platform_devices[] __initdata = { - &jz4740_udc_device, - &jz4740_udc_xceiv_device, - &jz4740_mmc_device, - &jz4740_nand_device, - &qi_lb60_keypad, - &qi_lb60_spigpio_device, - &jz4740_framebuffer_device, - &jz4740_pcm_device, - &jz4740_i2s_device, - &jz4740_codec_device, - &jz4740_adc_device, - &jz4740_pwm_device, - &jz4740_dma_device, - &qi_lb60_gpio_keys, - &qi_lb60_pwm_beeper, - &qi_lb60_charger_device, - &qi_lb60_audio_device, -}; - -static unsigned long pin_cfg_bias_disable[] = { - PIN_CONFIG_BIAS_DISABLE, -}; - -static struct pinctrl_map pin_map[] __initdata = { - /* NAND pin configuration */ - PIN_MAP_MUX_GROUP_DEFAULT("jz4740-nand", - "10010000.pin-controller", "nand-cs1", "nand"), - - /* fbdev pin configuration */ - PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_DEFAULT, - "10010000.pin-controller", "lcd-8bit", "lcd"), - PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_SLEEP, - "10010000.pin-controller", "lcd-no-pins", "lcd"), - - /* MMC pin configuration */ - PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0", - "10010000.pin-controller", "mmc-1bit", "mmc"), - PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0", - "10010000.pin-controller", "mmc-4bit", "mmc"), - PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0", - "10010000.pin-controller", "PD0", pin_cfg_bias_disable), - PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0", - "10010000.pin-controller", "PD2", pin_cfg_bias_disable), - - /* PWM pin configuration */ - PIN_MAP_MUX_GROUP_DEFAULT("jz4740-pwm", - "10010000.pin-controller", "pwm4", "pwm4"), -}; - - -static int __init qi_lb60_init_platform_devices(void) -{ - jz4740_framebuffer_device.dev.platform_data = &qi_lb60_fb_pdata; - jz4740_nand_device.dev.platform_data = &qi_lb60_nand_pdata; - jz4740_adc_device.dev.platform_data = &qi_lb60_battery_pdata; - jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata; - - gpiod_add_lookup_table(&qi_lb60_audio_gpio_table); - gpiod_add_lookup_table(&qi_lb60_nand_gpio_table); - gpiod_add_lookup_table(&qi_lb60_spigpio_gpio_table); - gpiod_add_lookup_table(&qi_lb60_mmc_gpio_table); - - spi_register_board_info(qi_lb60_spi_board_info, - ARRAY_SIZE(qi_lb60_spi_board_info)); - - pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup)); - pinctrl_register_mappings(pin_map, ARRAY_SIZE(pin_map)); - - return platform_add_devices(jz_platform_devices, - ARRAY_SIZE(jz_platform_devices)); - -} - -static int __init qi_lb60_board_setup(void) -{ - printk(KERN_INFO "Qi Hardware JZ4740 QI LB60 setup\n"); - - if (qi_lb60_init_platform_devices()) - panic("Failed to initialize platform devices"); - - return 0; -} -arch_initcall(qi_lb60_board_setup); diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c deleted file mode 100644 index c74c99f5951d..000000000000 --- a/arch/mips/jz4740/platform.c +++ /dev/null @@ -1,250 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> - * JZ4740 platform devices - */ - -#include <linux/clk.h> -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/resource.h> - -#include <linux/dma-mapping.h> - -#include <linux/usb/musb.h> - -#include <asm/mach-jz4740/platform.h> -#include <asm/mach-jz4740/base.h> -#include <asm/mach-jz4740/irq.h> - -#include <linux/serial_core.h> -#include <linux/serial_8250.h> - -/* USB Device Controller */ -struct platform_device jz4740_udc_xceiv_device = { - .name = "usb_phy_generic", - .id = 0, -}; - -static struct resource jz4740_udc_resources[] = { - [0] = { - .start = JZ4740_UDC_BASE_ADDR, - .end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = JZ4740_IRQ_UDC, - .end = JZ4740_IRQ_UDC, - .flags = IORESOURCE_IRQ, - .name = "mc", - }, -}; - -struct platform_device jz4740_udc_device = { - .name = "musb-jz4740", - .id = -1, - .dev = { - .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(jz4740_udc_resources), - .resource = jz4740_udc_resources, -}; - -/* MMC/SD controller */ -static struct resource jz4740_mmc_resources[] = { - { - .start = JZ4740_MSC_BASE_ADDR, - .end = JZ4740_MSC_BASE_ADDR + 0x1000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = JZ4740_IRQ_MSC, - .end = JZ4740_IRQ_MSC, - .flags = IORESOURCE_IRQ, - } -}; - -struct platform_device jz4740_mmc_device = { - .name = "jz4740-mmc", - .id = 0, - .dev = { - .dma_mask = &jz4740_mmc_device.dev.coherent_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(jz4740_mmc_resources), - .resource = jz4740_mmc_resources, -}; - -/* I2C controller */ -static struct resource jz4740_i2c_resources[] = { - { - .start = JZ4740_I2C_BASE_ADDR, - .end = JZ4740_I2C_BASE_ADDR + 0x1000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = JZ4740_IRQ_I2C, - .end = JZ4740_IRQ_I2C, - .flags = IORESOURCE_IRQ, - } -}; - -struct platform_device jz4740_i2c_device = { - .name = "jz4740-i2c", - .id = 0, - .num_resources = ARRAY_SIZE(jz4740_i2c_resources), - .resource = jz4740_i2c_resources, -}; - -/* NAND controller */ -static struct resource jz4740_nand_resources[] = { - { - .name = "mmio", - .start = JZ4740_EMC_BASE_ADDR, - .end = JZ4740_EMC_BASE_ADDR + 0x1000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "bank1", - .start = 0x18000000, - .end = 0x180C0000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "bank2", - .start = 0x14000000, - .end = 0x140C0000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "bank3", - .start = 0x0C000000, - .end = 0x0C0C0000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "bank4", - .start = 0x08000000, - .end = 0x080C0000 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device jz4740_nand_device = { - .name = "jz4740-nand", - .num_resources = ARRAY_SIZE(jz4740_nand_resources), - .resource = jz4740_nand_resources, -}; - -/* LCD controller */ -static struct resource jz4740_framebuffer_resources[] = { - { - .start = JZ4740_LCD_BASE_ADDR, - .end = JZ4740_LCD_BASE_ADDR + 0x1000 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device jz4740_framebuffer_device = { - .name = "jz4740-fb", - .id = -1, - .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources), - .resource = jz4740_framebuffer_resources, - .dev = { - .dma_mask = &jz4740_framebuffer_device.dev.coherent_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - -/* I2S controller */ -static struct resource jz4740_i2s_resources[] = { - { - .start = JZ4740_AIC_BASE_ADDR, - .end = JZ4740_AIC_BASE_ADDR + 0x38 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device jz4740_i2s_device = { - .name = "jz4740-i2s", - .id = -1, - .num_resources = ARRAY_SIZE(jz4740_i2s_resources), - .resource = jz4740_i2s_resources, -}; - -/* PCM */ -struct platform_device jz4740_pcm_device = { - .name = "jz4740-pcm-audio", - .id = -1, -}; - -/* Codec */ -static struct resource jz4740_codec_resources[] = { - { - .start = JZ4740_AIC_BASE_ADDR + 0x80, - .end = JZ4740_AIC_BASE_ADDR + 0x88 - 1, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device jz4740_codec_device = { - .name = "jz4740-codec", - .id = -1, - .num_resources = ARRAY_SIZE(jz4740_codec_resources), - .resource = jz4740_codec_resources, -}; - -/* ADC controller */ -static struct resource jz4740_adc_resources[] = { - { - .start = JZ4740_SADC_BASE_ADDR, - .end = JZ4740_SADC_BASE_ADDR + 0x30, - .flags = IORESOURCE_MEM, - }, - { - .start = JZ4740_IRQ_SADC, - .end = JZ4740_IRQ_SADC, - .flags = IORESOURCE_IRQ, - }, - { - .start = JZ4740_IRQ_ADC_BASE, - .end = JZ4740_IRQ_ADC_BASE, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device jz4740_adc_device = { - .name = "jz4740-adc", - .id = -1, - .num_resources = ARRAY_SIZE(jz4740_adc_resources), - .resource = jz4740_adc_resources, -}; - -/* PWM */ -struct platform_device jz4740_pwm_device = { - .name = "jz4740-pwm", - .id = -1, -}; - -/* DMA */ -static struct resource jz4740_dma_resources[] = { - { - .start = JZ4740_DMAC_BASE_ADDR, - .end = JZ4740_DMAC_BASE_ADDR + 0x400 - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = JZ4740_IRQ_DMAC, - .end = JZ4740_IRQ_DMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device jz4740_dma_device = { - .name = "jz4740-dma", - .id = -1, - .num_resources = ARRAY_SIZE(jz4740_dma_resources), - .resource = jz4740_dma_resources, -}; diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c index 88f33af4403b..ff4555c3fb15 100644 --- a/arch/mips/jz4740/prom.c +++ b/arch/mips/jz4740/prom.c @@ -4,15 +4,10 @@ * JZ4740 SoC prom code */ -#include <linux/kernel.h> #include <linux/init.h> -#include <linux/string.h> - -#include <linux/serial_reg.h> #include <asm/bootinfo.h> #include <asm/fw/fw.h> -#include <asm/mach-jz4740/base.h> void __init prom_init(void) { diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 4264eaf030c3..dc8ee21e0948 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c @@ -15,10 +15,9 @@ #include <asm/bootinfo.h> #include <asm/prom.h> -#include <asm/mach-jz4740/base.h> - #include "reset.h" +#define JZ4740_EMC_BASE_ADDR 0x13010000 #define JZ4740_EMC_SDRAM_CTRL 0x80 @@ -45,6 +44,8 @@ static void __init jz4740_detect_mem(void) static unsigned long __init get_board_mach_type(const void *fdt) { + if (!fdt_node_check_compatible(fdt, 0, "ingenic,x1000")) + return MACH_INGENIC_X1000; if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780")) return MACH_INGENIC_JZ4780; if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4770")) @@ -85,6 +86,8 @@ void __init device_tree_init(void) const char *get_system_type(void) { switch (mips_machtype) { + case MACH_INGENIC_X1000: + return "X1000"; case MACH_INGENIC_JZ4780: return "JZ4780"; case MACH_INGENIC_JZ4770: diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c index cb768e560d8b..5476899f0882 100644 --- a/arch/mips/jz4740/time.c +++ b/arch/mips/jz4740/time.c @@ -4,161 +4,14 @@ * JZ4740 platform time support */ -#include <linux/clk.h> #include <linux/clk-provider.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/time.h> +#include <linux/clocksource.h> -#include <linux/clockchips.h> -#include <linux/sched_clock.h> - -#include <asm/mach-jz4740/irq.h> #include <asm/mach-jz4740/timer.h> -#include <asm/time.h> - -#define TIMER_CLOCKEVENT 0 -#define TIMER_CLOCKSOURCE 1 - -static uint16_t jz4740_jiffies_per_tick; - -static u64 jz4740_clocksource_read(struct clocksource *cs) -{ - return jz4740_timer_get_count(TIMER_CLOCKSOURCE); -} - -static struct clocksource jz4740_clocksource = { - .name = "jz4740-timer", - .rating = 200, - .read = jz4740_clocksource_read, - .mask = CLOCKSOURCE_MASK(16), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static u64 notrace jz4740_read_sched_clock(void) -{ - return jz4740_timer_get_count(TIMER_CLOCKSOURCE); -} - -static irqreturn_t jz4740_clockevent_irq(int irq, void *devid) -{ - struct clock_event_device *cd = devid; - - jz4740_timer_ack_full(TIMER_CLOCKEVENT); - - if (!clockevent_state_periodic(cd)) - jz4740_timer_disable(TIMER_CLOCKEVENT); - - cd->event_handler(cd); - - return IRQ_HANDLED; -} - -static int jz4740_clockevent_set_periodic(struct clock_event_device *evt) -{ - jz4740_timer_set_count(TIMER_CLOCKEVENT, 0); - jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick); - jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); - jz4740_timer_enable(TIMER_CLOCKEVENT); - - return 0; -} - -static int jz4740_clockevent_resume(struct clock_event_device *evt) -{ - jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); - jz4740_timer_enable(TIMER_CLOCKEVENT); - - return 0; -} - -static int jz4740_clockevent_shutdown(struct clock_event_device *evt) -{ - jz4740_timer_disable(TIMER_CLOCKEVENT); - - return 0; -} - -static int jz4740_clockevent_set_next(unsigned long evt, - struct clock_event_device *cd) -{ - jz4740_timer_set_count(TIMER_CLOCKEVENT, 0); - jz4740_timer_set_period(TIMER_CLOCKEVENT, evt); - jz4740_timer_enable(TIMER_CLOCKEVENT); - - return 0; -} - -static struct clock_event_device jz4740_clockevent = { - .name = "jz4740-timer", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = jz4740_clockevent_set_next, - .set_state_shutdown = jz4740_clockevent_shutdown, - .set_state_periodic = jz4740_clockevent_set_periodic, - .set_state_oneshot = jz4740_clockevent_shutdown, - .tick_resume = jz4740_clockevent_resume, - .rating = 200, -#ifdef CONFIG_MACH_JZ4740 - .irq = JZ4740_IRQ_TCU0, -#endif -#if defined(CONFIG_MACH_JZ4770) || defined(CONFIG_MACH_JZ4780) - .irq = JZ4780_IRQ_TCU2, -#endif -}; - -static struct irqaction timer_irqaction = { - .handler = jz4740_clockevent_irq, - .flags = IRQF_PERCPU | IRQF_TIMER, - .name = "jz4740-timerirq", - .dev_id = &jz4740_clockevent, -}; void __init plat_time_init(void) { - int ret; - uint32_t clk_rate; - uint16_t ctrl; - struct clk *ext_clk; - of_clk_init(NULL); jz4740_timer_init(); - - ext_clk = clk_get(NULL, "ext"); - if (IS_ERR(ext_clk)) - panic("unable to get ext clock"); - clk_rate = clk_get_rate(ext_clk) >> 4; - clk_put(ext_clk); - - jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ); - - clockevent_set_clock(&jz4740_clockevent, clk_rate); - jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent); - jz4740_clockevent.min_delta_ticks = 100; - jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent); - jz4740_clockevent.max_delta_ticks = 0xffff; - jz4740_clockevent.cpumask = cpumask_of(0); - - clockevents_register_device(&jz4740_clockevent); - - ret = clocksource_register_hz(&jz4740_clocksource, clk_rate); - - if (ret) - printk(KERN_ERR "Failed to register clocksource: %d\n", ret); - - sched_clock_register(jz4740_read_sched_clock, 16, clk_rate); - - setup_irq(jz4740_clockevent.irq, &timer_irqaction); - - ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT; - - jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl); - jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl); - - jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick); - jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); - - jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff); - - jz4740_timer_enable(TIMER_CLOCKEVENT); - jz4740_timer_enable(TIMER_CLOCKSOURCE); + timer_probe(); } diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 1db29957a931..2c38f75d87ff 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -58,6 +58,7 @@ int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, unsigned long *contpc) { union mips_instruction insn = (union mips_instruction)dec_insn.insn; + int __maybe_unused bc_false = 0; if (!cpu_has_mmips) return 0; @@ -139,7 +140,6 @@ int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, #ifdef CONFIG_MIPS_FP_SUPPORT case mm_bc2f_op: case mm_bc1f_op: { - int bc_false = 0; unsigned int fcr31; unsigned int bit; diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 9635c1db3ae6..c2eb392597bf 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1384,15 +1384,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) break; } break; - case PRID_IMP_R4300: - c->cputype = CPU_R4300; - __cpu_name[cpu] = "R4300"; - set_isa(c, MIPS_CPU_ISA_III); - c->fpu_msk31 |= FPU_CSR_CONDX; - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; case PRID_IMP_R4600: c->cputype = CPU_R4600; __cpu_name[cpu] = "R4600"; @@ -1468,14 +1459,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) MIPS_CPU_LLSC; c->tlbsize = 48; break; - case PRID_IMP_R5432: - c->cputype = CPU_R5432; - __cpu_name[cpu] = "R5432"; - set_isa(c, MIPS_CPU_ISA_IV); - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_WATCH | MIPS_CPU_LLSC; - c->tlbsize = 48; - break; case PRID_IMP_R5500: c->cputype = CPU_R5500; __cpu_name[cpu] = "R5500"; @@ -1508,15 +1491,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) */ c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; break; - case PRID_IMP_R8000: - c->cputype = CPU_R8000; - __cpu_name[cpu] = "RM8000"; - set_isa(c, MIPS_CPU_ISA_IV); - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_LLSC; - c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ - break; case PRID_IMP_R10000: c->cputype = CPU_R10000; __cpu_name[cpu] = "R10000"; @@ -1573,6 +1547,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "ICT Loongson-3"; set_elf_platform(cpu, "loongson3a"); set_isa(c, MIPS_CPU_ISA_M64R1); + c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | + MIPS_ASE_LOONGSON_EXT); break; case PRID_REV_LOONGSON3B_R1: case PRID_REV_LOONGSON3B_R2: @@ -1580,6 +1556,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "ICT Loongson-3"; set_elf_platform(cpu, "loongson3b"); set_isa(c, MIPS_CPU_ISA_M64R1); + c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | + MIPS_ASE_LOONGSON_EXT); break; } @@ -1946,6 +1924,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) decode_configs(c); c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; c->writecombine = _CACHE_UNCACHED_ACCELERATED; + c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | + MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2); break; default: panic("Unknown Loongson Processor ID!"); @@ -1956,14 +1936,29 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) { decode_configs(c); - /* JZRISC does not implement the CP0 counter. */ + + /* + * XBurst misses a config2 register, so config3 decode was skipped in + * decode_configs(). + */ + decode_config3(c); + + /* XBurst does not implement the CP0 counter. */ c->options &= ~MIPS_CPU_COUNTER; BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter); + switch (c->processor_id & PRID_IMP_MASK) { - case PRID_IMP_JZRISC: - c->cputype = CPU_JZRISC; + case PRID_IMP_XBURST: + c->cputype = CPU_XBURST; c->writecombine = _CACHE_UNCACHED_ACCELERATED; __cpu_name[cpu] = "Ingenic JZRISC"; + /* + * The XBurst core by default attempts to avoid branch target + * buffer lookups by detecting & special casing loops. This + * feature will cause BogoMIPS and lpj calculate in error. + * Set cp0 config7 bit 4 to disable this feature. + */ + set_c0_config7(MIPS_CONF7_BTB_LOOP_EN); break; default: panic("Unknown Ingenic Processor ID!"); diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 398b905b027d..efde27c99414 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -32,9 +32,6 @@ NESTED(except_vec3_generic, 0, sp) .set push .set noat -#if R5432_CP0_INTERRUPT_WAR - mfc0 k0, CP0_INDEX -#endif mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c #ifdef CONFIG_64BIT diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 7388f1374d5f..eb2afc0b8db1 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -151,7 +151,6 @@ void __init check_wait(void) cpu_wait = r39xx_wait; break; case CPU_R4200: -/* case CPU_R4300: */ case CPU_R4600: case CPU_R4640: case CPU_R4650: @@ -173,7 +172,7 @@ void __init check_wait(void) case CPU_CAVIUM_OCTEON_PLUS: case CPU_CAVIUM_OCTEON2: case CPU_CAVIUM_OCTEON3: - case CPU_JZRISC: + case CPU_XBURST: case CPU_LOONGSON1: case CPU_XLR: case CPU_XLP: diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index b2de408a259e..f8d36710cd58 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -124,6 +124,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (cpu_has_eva) seq_printf(m, "%s", " eva"); if (cpu_has_htw) seq_printf(m, "%s", " htw"); if (cpu_has_xpa) seq_printf(m, "%s", " xpa"); + if (cpu_has_loongson_mmi) seq_printf(m, "%s", " loongson-mmi"); + if (cpu_has_loongson_cam) seq_printf(m, "%s", " loongson-cam"); + if (cpu_has_loongson_ext) seq_printf(m, "%s", " loongson-ext"); + if (cpu_has_loongson_ext2) seq_printf(m, "%s", " loongson-ext2"); seq_printf(m, "\n"); if (cpu_has_mmips) { diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index d9434cd0f568..b449b68662a9 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -217,7 +217,7 @@ einval: li v0, -ENOSYS #define sys_sched_getaffinity mipsmt_sys_sched_getaffinity #endif /* CONFIG_MIPS_MT_FPAFF */ -#define __SYSCALL(nr, entry, nargs) PTR entry +#define __SYSCALL(nr, entry) PTR entry .align 2 .type sys_call_table, @object EXPORT(sys_call_table) diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index c761ddfed9e6..35d8c86b160e 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -101,7 +101,7 @@ not_n32_scall: END(handle_sysn32) -#define __SYSCALL(nr, entry, nargs) PTR entry +#define __SYSCALL(nr, entry) PTR entry .type sysn32_call_table, @object EXPORT(sysn32_call_table) #include <asm/syscall_table_64_n32.h> diff --git a/arch/mips/kernel/scall64-n64.S b/arch/mips/kernel/scall64-n64.S index 727fb8a1b0eb..23b2e2b1609c 100644 --- a/arch/mips/kernel/scall64-n64.S +++ b/arch/mips/kernel/scall64-n64.S @@ -109,7 +109,7 @@ illegal_syscall: j n64_syscall_exit END(handle_sys64) -#define __SYSCALL(nr, entry, nargs) PTR entry +#define __SYSCALL(nr, entry) PTR entry .align 3 .type sys_call_table, @object EXPORT(sys_call_table) diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index feb2653490df..41df8221bb8f 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -213,7 +213,7 @@ einval: li v0, -ENOSYS jr ra END(sys32_syscall) -#define __SYSCALL(nr, entry, nargs) PTR entry +#define __SYSCALL(nr, entry) PTR entry .align 3 .type sys32_call_table,@object EXPORT(sys32_call_table) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index ab349d2381c3..b8249c233754 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -63,8 +63,6 @@ unsigned long mips_machtype __read_mostly = MACH_UNKNOWN; EXPORT_SYMBOL(mips_machtype); -struct boot_mem_map boot_mem_map; - static char __initdata command_line[COMMAND_LINE_SIZE]; char __initdata arcs_cmdline[COMMAND_LINE_SIZE]; @@ -76,7 +74,7 @@ static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; * mips_io_port_base is the begin of the address space to which x86 style * I/O ports are mapped. */ -const unsigned long mips_io_port_base = -1; +unsigned long mips_io_port_base = -1; EXPORT_SYMBOL(mips_io_port_base); static struct resource code_resource = { .name = "Kernel code", }; @@ -92,8 +90,10 @@ EXPORT_SYMBOL(ARCH_PFN_OFFSET); void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type) { - int x = boot_mem_map.nr_map; - int i; + /* + * Note: This function only exists for historical reason, + * new code should use memblock_add or memblock_add_node instead. + */ /* * If the region reaches the top of the physical address space, adjust @@ -108,38 +108,20 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type) return; } - /* - * Try to merge with existing entry, if any. - */ - for (i = 0; i < boot_mem_map.nr_map; i++) { - struct boot_mem_map_entry *entry = boot_mem_map.map + i; - unsigned long top; - - if (entry->type != type) - continue; - - if (start + size < entry->addr) - continue; /* no overlap */ + memblock_add(start, size); + /* Reserve any memory except the ordinary RAM ranges. */ + switch (type) { + case BOOT_MEM_RAM: + break; - if (entry->addr + entry->size < start) - continue; /* no overlap */ + case BOOT_MEM_NOMAP: /* Discard the range from the system. */ + memblock_remove(start, size); + break; - top = max(entry->addr + entry->size, start + size); - entry->addr = min(entry->addr, start); - entry->size = top - entry->addr; - - return; + default: /* Reserve the rest of the memory types at boot time */ + memblock_reserve(start, size); + break; } - - if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) { - pr_err("Ooops! Too many entries in the memory map!\n"); - return; - } - - boot_mem_map.map[x].addr = start; - boot_mem_map.map[x].size = size; - boot_mem_map.map[x].type = type; - boot_mem_map.nr_map++; } void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) @@ -161,70 +143,6 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add add_memory_region(start, size, BOOT_MEM_RAM); } -static bool __init __maybe_unused memory_region_available(phys_addr_t start, - phys_addr_t size) -{ - int i; - bool in_ram = false, free = true; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - phys_addr_t start_, end_; - - start_ = boot_mem_map.map[i].addr; - end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size; - - switch (boot_mem_map.map[i].type) { - case BOOT_MEM_RAM: - if (start >= start_ && start + size <= end_) - in_ram = true; - break; - case BOOT_MEM_RESERVED: - case BOOT_MEM_NOMAP: - if ((start >= start_ && start < end_) || - (start < start_ && start + size >= start_)) - free = false; - break; - default: - continue; - } - } - - return in_ram && free; -} - -static void __init print_memory_map(void) -{ - int i; - const int field = 2 * sizeof(unsigned long); - - for (i = 0; i < boot_mem_map.nr_map; i++) { - printk(KERN_INFO " memory: %0*Lx @ %0*Lx ", - field, (unsigned long long) boot_mem_map.map[i].size, - field, (unsigned long long) boot_mem_map.map[i].addr); - - switch (boot_mem_map.map[i].type) { - case BOOT_MEM_RAM: - printk(KERN_CONT "(usable)\n"); - break; - case BOOT_MEM_INIT_RAM: - printk(KERN_CONT "(usable after init)\n"); - break; - case BOOT_MEM_ROM_DATA: - printk(KERN_CONT "(ROM data)\n"); - break; - case BOOT_MEM_RESERVED: - printk(KERN_CONT "(reserved)\n"); - break; - case BOOT_MEM_NOMAP: - printk(KERN_CONT "(nomap)\n"); - break; - default: - printk(KERN_CONT "type %lu\n", boot_mem_map.map[i].type); - break; - } - } -} - /* * Manage initrd */ @@ -376,8 +294,11 @@ static void __init bootmem_init(void) static void __init bootmem_init(void) { - phys_addr_t ramstart = PHYS_ADDR_MAX; - int i; + struct memblock_region *mem; + phys_addr_t ramstart, ramend; + + ramstart = memblock_start_of_DRAM(); + ramend = memblock_end_of_DRAM(); /* * Sanity check any INITRD first. We don't take it into account @@ -391,122 +312,66 @@ static void __init bootmem_init(void) memblock_reserve(__pa_symbol(&_text), __pa_symbol(&_end) - __pa_symbol(&_text)); + /* max_low_pfn is not a number of pages but the end pfn of low mem */ + +#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET + ARCH_PFN_OFFSET = PFN_UP(ramstart); +#else /* - * max_low_pfn is not a number of pages. The number of pages - * of the system is given by 'max_low_pfn - min_low_pfn'. + * Reserve any memory between the start of RAM and PHYS_OFFSET */ - min_low_pfn = ~0UL; - max_low_pfn = 0; - - /* Find the highest and lowest page frame numbers we have available. */ - for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long start, end; - - if (boot_mem_map.map[i].type != BOOT_MEM_RAM) - continue; + if (ramstart > PHYS_OFFSET) + memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET); - start = PFN_UP(boot_mem_map.map[i].addr); - end = PFN_DOWN(boot_mem_map.map[i].addr - + boot_mem_map.map[i].size); + if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) { + pr_info("Wasting %lu bytes for tracking %lu unused pages\n", + (unsigned long)((PFN_UP(ramstart) - ARCH_PFN_OFFSET) * sizeof(struct page)), + (unsigned long)(PFN_UP(ramstart) - ARCH_PFN_OFFSET)); + } +#endif - ramstart = min(ramstart, boot_mem_map.map[i].addr); + min_low_pfn = ARCH_PFN_OFFSET; + max_pfn = PFN_DOWN(ramend); + for_each_memblock(memory, mem) { + unsigned long start = memblock_region_memory_base_pfn(mem); + unsigned long end = memblock_region_memory_end_pfn(mem); -#ifndef CONFIG_HIGHMEM /* * Skip highmem here so we get an accurate max_low_pfn if low * memory stops short of high memory. * If the region overlaps HIGHMEM_START, end is clipped so * max_pfn excludes the highmem portion. */ + if (memblock_is_nomap(mem)) + continue; if (start >= PFN_DOWN(HIGHMEM_START)) continue; if (end > PFN_DOWN(HIGHMEM_START)) end = PFN_DOWN(HIGHMEM_START); -#endif - if (end > max_low_pfn) max_low_pfn = end; - if (start < min_low_pfn) - min_low_pfn = start; } if (min_low_pfn >= max_low_pfn) panic("Incorrect memory mapping !!!"); -#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET - ARCH_PFN_OFFSET = PFN_UP(ramstart); -#else - /* - * Reserve any memory between the start of RAM and PHYS_OFFSET - */ - if (ramstart > PHYS_OFFSET) { - add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET, - BOOT_MEM_RESERVED); - memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET); - } - - if (min_low_pfn > ARCH_PFN_OFFSET) { - pr_info("Wasting %lu bytes for tracking %lu unused pages\n", - (min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page), - min_low_pfn - ARCH_PFN_OFFSET); - } else if (ARCH_PFN_OFFSET - min_low_pfn > 0UL) { - pr_info("%lu free pages won't be used\n", - ARCH_PFN_OFFSET - min_low_pfn); - } - min_low_pfn = ARCH_PFN_OFFSET; -#endif - - /* - * Determine low and high memory ranges - */ - max_pfn = max_low_pfn; - if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) { + if (max_pfn > PFN_DOWN(HIGHMEM_START)) { #ifdef CONFIG_HIGHMEM highstart_pfn = PFN_DOWN(HIGHMEM_START); - highend_pfn = max_low_pfn; -#endif + highend_pfn = max_pfn; +#else max_low_pfn = PFN_DOWN(HIGHMEM_START); - } - - /* Install all valid RAM ranges to the memblock memory region */ - for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long start, end; - - start = PFN_UP(boot_mem_map.map[i].addr); - end = PFN_DOWN(boot_mem_map.map[i].addr - + boot_mem_map.map[i].size); - - if (start < min_low_pfn) - start = min_low_pfn; -#ifndef CONFIG_HIGHMEM - /* Ignore highmem regions if highmem is unsupported */ - if (end > max_low_pfn) - end = max_low_pfn; + max_pfn = max_low_pfn; #endif - if (end <= start) - continue; - - memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0); + } - /* Reserve any memory except the ordinary RAM ranges. */ - switch (boot_mem_map.map[i].type) { - case BOOT_MEM_RAM: - break; - case BOOT_MEM_NOMAP: /* Discard the range from the system. */ - memblock_remove(PFN_PHYS(start), PFN_PHYS(end - start)); - continue; - default: /* Reserve the rest of the memory types at boot time */ - memblock_reserve(PFN_PHYS(start), PFN_PHYS(end - start)); - break; - } - /* - * In any case the added to the memblock memory regions - * (highmem/lowmem, available/reserved, etc) are considered - * as present, so inform sparsemem about them. - */ - memory_present(0, start, end); - } + /* + * In any case the added to the memblock memory regions + * (highmem/lowmem, available/reserved, etc) are considered + * as present, so inform sparsemem about them. + */ + memblocks_present(); /* * Reserve initrd memory if needed. @@ -528,8 +393,9 @@ static int __init early_parse_mem(char *p) * size. */ if (usermem == 0) { - boot_mem_map.nr_map = 0; usermem = 1; + memblock_remove(memblock_start_of_DRAM(), + memblock_end_of_DRAM() - memblock_start_of_DRAM()); } start = 0; size = memparse(p, &p); @@ -586,14 +452,13 @@ early_param("memmap", early_parse_memmap); unsigned long setup_elfcorehdr, setup_elfcorehdr_size; static int __init early_parse_elfcorehdr(char *p) { - int i; + struct memblock_region *mem; setup_elfcorehdr = memparse(p, &p); - for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long start = boot_mem_map.map[i].addr; - unsigned long end = (boot_mem_map.map[i].addr + - boot_mem_map.map[i].size); + for_each_memblock(memory, mem) { + unsigned long start = mem->base; + unsigned long end = start + mem->size; if (setup_elfcorehdr >= start && setup_elfcorehdr < end) { /* * Reserve from the elf core header to the end of @@ -613,47 +478,20 @@ static int __init early_parse_elfcorehdr(char *p) early_param("elfcorehdr", early_parse_elfcorehdr); #endif -static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type) -{ - phys_addr_t size; - int i; - - size = end - mem; - if (!size) - return; - - /* Make sure it is in the boot_mem_map */ - for (i = 0; i < boot_mem_map.nr_map; i++) { - if (mem >= boot_mem_map.map[i].addr && - mem < (boot_mem_map.map[i].addr + - boot_mem_map.map[i].size)) - return; - } - add_memory_region(mem, size, type); -} - #ifdef CONFIG_KEXEC -static inline unsigned long long get_total_mem(void) -{ - unsigned long long total; - - total = max_pfn - min_low_pfn; - return total << PAGE_SHIFT; -} - static void __init mips_parse_crashkernel(void) { unsigned long long total_mem; unsigned long long crash_size, crash_base; int ret; - total_mem = get_total_mem(); + total_mem = memblock_phys_mem_size(); ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base); if (ret != 0 || crash_size <= 0) return; - if (!memory_region_available(crash_base, crash_size)) { + if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 0)) { pr_warn("Invalid memory region reserved for crash kernel\n"); return; } @@ -686,6 +524,17 @@ static void __init request_crashkernel(struct resource *res) } #endif /* !defined(CONFIG_KEXEC) */ +static void __init check_kernel_sections_mem(void) +{ + phys_addr_t start = PFN_PHYS(PFN_DOWN(__pa_symbol(&_text))); + phys_addr_t size = PFN_PHYS(PFN_UP(__pa_symbol(&_end))) - start; + + if (!memblock_is_region_memory(start, size)) { + pr_info("Kernel sections are not in the memory maps\n"); + memblock_add(start, size); + } +} + #define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) #define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) #define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) @@ -731,25 +580,6 @@ static void __init arch_mem_init(char **cmdline_p) plat_mem_setup(); memblock_set_bottom_up(true); - /* - * Make sure all kernel memory is in the maps. The "UP" and - * "DOWN" are opposite for initdata since if it crosses over - * into another memory section you don't want that to be - * freed when the initdata is freed. - */ - arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT, - PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT, - BOOT_MEM_RAM); - arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT, - PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT, - BOOT_MEM_INIT_RAM); - arch_mem_addpart(PFN_DOWN(__pa_symbol(&__bss_start)) << PAGE_SHIFT, - PFN_UP(__pa_symbol(&__bss_stop)) << PAGE_SHIFT, - BOOT_MEM_RAM); - - pr_info("Determined physical RAM map:\n"); - print_memory_map(); - #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE) strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); #else @@ -783,14 +613,17 @@ static void __init arch_mem_init(char **cmdline_p) parse_early_param(); - if (usermem) { - pr_info("User-defined physical RAM map:\n"); - print_memory_map(); - } + if (usermem) + pr_info("User-defined physical RAM map overwrite\n"); + + check_kernel_sections_mem(); early_init_fdt_reserve_self(); early_init_fdt_scan_reserved_mem(); +#ifndef CONFIG_NUMA + memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); +#endif bootmem_init(); /* @@ -830,12 +663,12 @@ static void __init arch_mem_init(char **cmdline_p) memblock_dump_all(); - early_memtest(PFN_PHYS(min_low_pfn), PFN_PHYS(max_low_pfn)); + early_memtest(PFN_PHYS(ARCH_PFN_OFFSET), PFN_PHYS(max_low_pfn)); } static void __init resource_init(void) { - int i; + struct memblock_region *region; if (UNCAC_BASE != IO_BASE) return; @@ -847,16 +680,10 @@ static void __init resource_init(void) bss_resource.start = __pa_symbol(&__bss_start); bss_resource.end = __pa_symbol(&__bss_stop) - 1; - for (i = 0; i < boot_mem_map.nr_map; i++) { + for_each_memblock(memory, region) { + phys_addr_t start = PFN_PHYS(memblock_region_memory_base_pfn(region)); + phys_addr_t end = PFN_PHYS(memblock_region_memory_end_pfn(region)) - 1; struct resource *res; - unsigned long start, end; - - start = boot_mem_map.map[i].addr; - end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; - if (start >= HIGHMEM_START) - continue; - if (end >= HIGHMEM_START) - end = HIGHMEM_START - 1; res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); if (!res) @@ -865,20 +692,8 @@ static void __init resource_init(void) res->start = start; res->end = end; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - - switch (boot_mem_map.map[i].type) { - case BOOT_MEM_RAM: - case BOOT_MEM_INIT_RAM: - case BOOT_MEM_ROM_DATA: - res->name = "System RAM"; - res->flags |= IORESOURCE_SYSRAM; - break; - case BOOT_MEM_RESERVED: - case BOOT_MEM_NOMAP: - default: - res->name = "reserved"; - } + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + res->name = "System RAM"; request_resource(&iomem_resource, res); diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index b6dc78ad5d8c..b0e25e913bdb 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -132,6 +132,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) [efault] "i" (-EFAULT) : "memory"); } else if (cpu_has_llsc) { + loongson_llsc_mb(); __asm__ __volatile__ ( " .set push \n" " .set "MIPS_ISA_ARCH_LEVEL" \n" diff --git a/arch/mips/kernel/syscalls/syscalltbl.sh b/arch/mips/kernel/syscalls/syscalltbl.sh index acd338d33bbe..1e2570740c20 100644 --- a/arch/mips/kernel/syscalls/syscalltbl.sh +++ b/arch/mips/kernel/syscalls/syscalltbl.sh @@ -13,10 +13,10 @@ emit() { t_entry="$3" while [ $t_nxt -lt $t_nr ]; do - printf "__SYSCALL(%s, sys_ni_syscall, )\n" "${t_nxt}" + printf "__SYSCALL(%s,sys_ni_syscall)\n" "${t_nxt}" t_nxt=$((t_nxt+1)) done - printf "__SYSCALL(%s, %s, )\n" "${t_nxt}" "${t_entry}" + printf "__SYSCALL(%s,%s)\n" "${t_nxt}" "${t_entry}" } grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 3a372686ffca..bc35f8499111 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -20,9 +20,12 @@ #include <asm/mips-cps.h> #include <asm/page.h> #include <asm/vdso.h> +#include <vdso/helpers.h> +#include <vdso/vsyscall.h> /* Kernel-provided data used by the VDSO. */ -static union mips_vdso_data vdso_data __page_aligned_data; +static union mips_vdso_data mips_vdso_data __page_aligned_data; +struct vdso_data *vdso_data = mips_vdso_data.data; /* * Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as @@ -66,34 +69,6 @@ static int __init init_vdso(void) } subsys_initcall(init_vdso); -void update_vsyscall(struct timekeeper *tk) -{ - vdso_data_write_begin(&vdso_data); - - vdso_data.xtime_sec = tk->xtime_sec; - vdso_data.xtime_nsec = tk->tkr_mono.xtime_nsec; - vdso_data.wall_to_mono_sec = tk->wall_to_monotonic.tv_sec; - vdso_data.wall_to_mono_nsec = tk->wall_to_monotonic.tv_nsec; - vdso_data.cs_shift = tk->tkr_mono.shift; - - vdso_data.clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode; - if (vdso_data.clock_mode != VDSO_CLOCK_NONE) { - vdso_data.cs_mult = tk->tkr_mono.mult; - vdso_data.cs_cycle_last = tk->tkr_mono.cycle_last; - vdso_data.cs_mask = tk->tkr_mono.mask; - } - - vdso_data_write_end(&vdso_data); -} - -void update_vsyscall_tz(void) -{ - if (vdso_data.clock_mode != VDSO_CLOCK_NONE) { - vdso_data.tz_minuteswest = sys_tz.tz_minuteswest; - vdso_data.tz_dsttime = sys_tz.tz_dsttime; - } -} - static unsigned long vdso_base(void) { unsigned long base; @@ -163,7 +138,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) */ if (cpu_has_dc_aliases) { base = __ALIGN_MASK(base, shm_align_mask); - base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask; + base += ((unsigned long)vdso_data - gic_size) & shm_align_mask; } data_addr = base + gic_size; @@ -189,7 +164,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) /* Map data page. */ ret = remap_pfn_range(vma, data_addr, - virt_to_phys(&vdso_data) >> PAGE_SHIFT, + virt_to_phys(vdso_data) >> PAGE_SHIFT, PAGE_SIZE, PAGE_READONLY); if (ret) goto out; diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index b4323b2214e2..156a95ac5c72 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -468,14 +468,14 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P); clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P); /* rc 0 */ - clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P); + clkdev_add_pmu("1f106800.phy", "phy", 1, 2, PMU_ANALOG_PCIE0_P); clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); - clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI); + clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI); clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL); /* rc 1 */ - clkdev_add_pmu("19000000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE1_P); + clkdev_add_pmu("1f700400.phy", "phy", 1, 2, PMU_ANALOG_PCIE1_P); clkdev_add_pmu("19000000.pcie", "msi", 1, 1, PMU1_PCIE1_MSI); - clkdev_add_pmu("19000000.pcie", "pdi", 1, 1, PMU1_PCIE1_PDI); + clkdev_add_pmu("1f700400.phy", "pdi", 1, 1, PMU1_PCIE1_PDI); clkdev_add_pmu("19000000.pcie", "ctl", 1, 1, PMU1_PCIE1_CTL); } @@ -499,9 +499,9 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); /* rc 2 */ - clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); + clkdev_add_pmu("1f106a00.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI); - clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI); + clkdev_add_pmu("1f106a00.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI); clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL); clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP); clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); @@ -526,10 +526,10 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM); - clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY); + clkdev_add_pmu("1f106800.phy", "phy", 1, 1, PMU1_PCIE_PHY); clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK); clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); - clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI); + clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI); clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL); clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS); diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 1e8d335025d7..46f483e952c8 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -28,11 +28,11 @@ obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_DMA_NONCOHERENT) += dma-noncoherent.o +obj-$(CONFIG_CPU_R3K_TLB) += tlb-r3k.o obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o -obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o -obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o +obj-$(CONFIG_CPU_R3000) += c-r3k.o obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o -obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o +obj-$(CONFIG_CPU_TX39XX) += c-tx39.o obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 5166e38cd1c6..89b9c851d822 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1098,7 +1098,6 @@ static void probe_pcache(void) c->options |= MIPS_CPU_CACHE_CDEX_P; break; - case CPU_R5432: case CPU_R5500: icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); @@ -1134,7 +1133,6 @@ static void probe_pcache(void) case CPU_R4400PC: case CPU_R4400SC: case CPU_R4400MC: - case CPU_R4300: icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); c->icache.ways = 1; diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 8a038b30d3c4..090fa653dfa9 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -269,37 +269,46 @@ void __init fixrange_init(unsigned long start, unsigned long end, #endif } -unsigned __weak platform_maar_init(unsigned num_pairs) +struct maar_walk_info { + struct maar_config cfg[16]; + unsigned int num_cfg; +}; + +static int maar_res_walk(unsigned long start_pfn, unsigned long nr_pages, + void *data) { - struct maar_config cfg[BOOT_MEM_MAP_MAX]; - unsigned i, num_configured, num_cfg = 0; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - switch (boot_mem_map.map[i].type) { - case BOOT_MEM_RAM: - case BOOT_MEM_INIT_RAM: - break; - default: - continue; - } + struct maar_walk_info *wi = data; + struct maar_config *cfg = &wi->cfg[wi->num_cfg]; + unsigned int maar_align; - /* Round lower up */ - cfg[num_cfg].lower = boot_mem_map.map[i].addr; - cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff; + /* MAAR registers hold physical addresses right shifted by 4 bits */ + maar_align = BIT(MIPS_MAAR_ADDR_SHIFT + 4); - /* Round upper down */ - cfg[num_cfg].upper = boot_mem_map.map[i].addr + - boot_mem_map.map[i].size; - cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1; + /* Fill in the MAAR config entry */ + cfg->lower = ALIGN(PFN_PHYS(start_pfn), maar_align); + cfg->upper = ALIGN_DOWN(PFN_PHYS(start_pfn + nr_pages), maar_align) - 1; + cfg->attrs = MIPS_MAAR_S; + + /* Ensure we don't overflow the cfg array */ + if (!WARN_ON(wi->num_cfg >= ARRAY_SIZE(wi->cfg))) + wi->num_cfg++; + + return 0; +} - cfg[num_cfg].attrs = MIPS_MAAR_S; - num_cfg++; - } - num_configured = maar_config(cfg, num_cfg, num_pairs); - if (num_configured < num_cfg) - pr_warn("Not enough MAAR pairs (%u) for all bootmem regions (%u)\n", - num_pairs, num_cfg); +unsigned __weak platform_maar_init(unsigned num_pairs) +{ + unsigned int num_configured; + struct maar_walk_info wi; + + wi.num_cfg = 0; + walk_system_ram_range(0, max_pfn, &wi, maar_res_walk); + + num_configured = maar_config(wi.cfg, wi.num_cfg, num_pairs); + if (num_configured < wi.num_cfg) + pr_warn("Not enough MAAR pairs (%u) for all memory regions (%u)\n", + num_pairs, wi.num_cfg); return num_configured; } @@ -382,33 +391,6 @@ void maar_init(void) } #ifndef CONFIG_NEED_MULTIPLE_NODES -int page_is_ram(unsigned long pagenr) -{ - int i; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long addr, end; - - switch (boot_mem_map.map[i].type) { - case BOOT_MEM_RAM: - case BOOT_MEM_INIT_RAM: - break; - default: - /* not usable memory */ - continue; - } - - addr = PFN_UP(boot_mem_map.map[i].addr); - end = PFN_DOWN(boot_mem_map.map[i].addr + - boot_mem_map.map[i].size); - - if (pagenr >= addr && pagenr < end) - return 1; - } - - return 0; -} - void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; @@ -443,7 +425,7 @@ void __init paging_init(void) static struct kcore_list kcore_kseg0; #endif -static inline void mem_init_free_highmem(void) +static inline void __init mem_init_free_highmem(void) { #ifdef CONFIG_HIGHMEM unsigned long tmp; @@ -454,7 +436,7 @@ static inline void mem_init_free_highmem(void) for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { struct page *page = pfn_to_page(tmp); - if (!page_is_ram(tmp)) + if (!memblock_is_memory(PFN_PHYS(tmp))) SetPageReserved(page); else free_highmem_page(page); @@ -464,6 +446,12 @@ static inline void mem_init_free_highmem(void) void __init mem_init(void) { + /* + * When _PFN_SHIFT is greater than PAGE_SHIFT we won't have enough PTE + * bits to hold a full 32b physical address on MIPS32 systems. + */ + BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (_PFN_SHIFT > PAGE_SHIFT)); + #ifdef CONFIG_HIGHMEM #ifdef CONFIG_DISCONTIGMEM #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet" diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c index e2a33adc0f29..6416a531a4c3 100644 --- a/arch/mips/mm/pgtable-32.c +++ b/arch/mips/mm/pgtable-32.c @@ -12,6 +12,7 @@ #include <asm/fixmap.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> +#include <asm/tlbflush.h> void pgd_init(unsigned long page) { @@ -30,6 +31,25 @@ void pgd_init(unsigned long page) } } +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) +pmd_t mk_pmd(struct page *page, pgprot_t prot) +{ + pmd_t pmd; + + pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot); + + return pmd; +} + + +void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd) +{ + *pmdp = pmd; + flush_tlb_all(); +} +#endif /* defined(CONFIG_TRANSPARENT_HUGEPAGE) */ + void __init pagetable_init(void) { unsigned long vaddr; diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 394673991bab..dbdbfe5d8408 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c @@ -221,13 +221,26 @@ static inline int __init mips_sc_probe(void) else return 0; - /* - * According to config2 it would be 5-ways, but that is contradicted - * by all documentation. - */ - if (current_cpu_type() == CPU_JZRISC && - mips_machtype == MACH_INGENIC_JZ4770) - c->scache.ways = 4; + if (current_cpu_type() == CPU_XBURST) { + switch (mips_machtype) { + /* + * According to config2 it would be 5-ways, but that is + * contradicted by all documentation. + */ + case MACH_INGENIC_JZ4770: + c->scache.ways = 4; + break; + + /* + * According to config2 it would be 5-ways and 512-sets, + * but that is contradicted by all documentation. + */ + case MACH_INGENIC_X1000: + c->scache.sets = 256; + c->scache.ways = 4; + break; + } + } c->scache.waysize = c->scache.sets * c->scache.linesz; c->scache.waybit = __ffs(c->scache.waysize); diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c deleted file mode 100644 index c1e9e144007e..000000000000 --- a/arch/mips/mm/tlb-r8k.c +++ /dev/null @@ -1,239 +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. - * - * Copyright (C) 1996 David S. Miller (davem@davemloft.net) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/sched.h> -#include <linux/smp.h> -#include <linux/mm.h> - -#include <asm/cpu.h> -#include <asm/bootinfo.h> -#include <asm/mmu_context.h> -#include <asm/pgtable.h> - -extern void build_tlb_refill_handler(void); - -#define TFP_TLB_SIZE 384 -#define TFP_TLB_SET_SHIFT 7 - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = read_c0_entryhi(); - write_c0_entrylo(0); - - for (entry = 0; entry < TFP_TLB_SIZE; entry++) { - write_c0_tlbset(entry >> TFP_TLB_SET_SHIFT); - write_c0_vaddr(entry << PAGE_SHIFT); - write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1))); - mtc0_tlbw_hazard(); - tlb_write(); - } - tlbw_use_hazard(); - write_c0_entryhi(old_ctx); - local_irq_restore(flags); -} - -void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - int cpu = smp_processor_id(); - unsigned long flags; - int oldpid, newpid, size; - - if (!cpu_context(cpu, mm)) - return; - - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - - local_irq_save(flags); - - if (size > TFP_TLB_SIZE / 2) { - drop_mmu_context(mm); - goto out_restore; - } - - oldpid = read_c0_entryhi(); - newpid = cpu_asid(cpu, mm); - - write_c0_entrylo(0); - - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; - while (start < end) { - signed long idx; - - write_c0_vaddr(start); - write_c0_entryhi(start); - start += PAGE_SIZE; - tlb_probe(); - idx = read_c0_tlbset(); - if (idx < 0) - continue; - - write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); - tlb_write(); - } - write_c0_entryhi(oldpid); - -out_restore: - local_irq_restore(flags); -} - -/* Usable for KV1 addresses only! */ -void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) -{ - unsigned long size, flags; - - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - - if (size > TFP_TLB_SIZE / 2) { - local_flush_tlb_all(); - return; - } - - local_irq_save(flags); - - write_c0_entrylo(0); - - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; - while (start < end) { - signed long idx; - - write_c0_vaddr(start); - write_c0_entryhi(start); - start += PAGE_SIZE; - tlb_probe(); - idx = read_c0_tlbset(); - if (idx < 0) - continue; - - write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); - tlb_write(); - } - - local_irq_restore(flags); -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - int cpu = smp_processor_id(); - unsigned long flags; - int oldpid, newpid; - signed long idx; - - if (!cpu_context(cpu, vma->vm_mm)) - return; - - newpid = cpu_asid(cpu, vma->vm_mm); - page &= PAGE_MASK; - local_irq_save(flags); - oldpid = read_c0_entryhi(); - write_c0_vaddr(page); - write_c0_entryhi(newpid); - tlb_probe(); - idx = read_c0_tlbset(); - if (idx < 0) - goto finish; - - write_c0_entrylo(0); - write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); - tlb_write(); - -finish: - write_c0_entryhi(oldpid); - local_irq_restore(flags); -} - -/* - * We will need multiple versions of update_mmu_cache(), one that just - * updates the TLB with the new pte(s), and another which also checks - * for the R4k "end of page" hardware bug and does the needy. - */ -void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data); - - local_irq_save(flags); - address &= PAGE_MASK; - write_c0_vaddr(address); - write_c0_entryhi(pid); - pgdp = pgd_offset(vma->vm_mm, address); - pmdp = pmd_offset(pgdp, address); - ptep = pte_offset_map(pmdp, address); - tlb_probe(); - - write_c0_entrylo(pte_val(*ptep++) >> 6); - tlb_write(); - - write_c0_entryhi(pid); - local_irq_restore(flags); -} - -static void probe_tlb(unsigned long config) -{ - struct cpuinfo_mips *c = ¤t_cpu_data; - - c->tlbsize = 3 * 128; /* 3 sets each 128 entries */ -} - -void tlb_init(void) -{ - unsigned int config = read_c0_config(); - unsigned long status; - - probe_tlb(config); - - status = read_c0_status(); - status &= ~(ST0_UPS | ST0_KPS); -#ifdef CONFIG_PAGE_SIZE_4KB - status |= (TFP_PAGESIZE_4K << 32) | (TFP_PAGESIZE_4K << 36); -#elif defined(CONFIG_PAGE_SIZE_8KB) - status |= (TFP_PAGESIZE_8K << 32) | (TFP_PAGESIZE_8K << 36); -#elif defined(CONFIG_PAGE_SIZE_16KB) - status |= (TFP_PAGESIZE_16K << 32) | (TFP_PAGESIZE_16K << 36); -#elif defined(CONFIG_PAGE_SIZE_64KB) - status |= (TFP_PAGESIZE_64K << 32) | (TFP_PAGESIZE_64K << 36); -#endif - write_c0_status(status); - - write_c0_wired(0); - - local_flush_tlb_all(); - - build_tlb_refill_handler(); -} diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 144ceb0fba88..e01cb33bfa1a 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -545,7 +545,6 @@ void build_tlb_write_entry(u32 **p, struct uasm_label **l, tlbw(p); break; - case CPU_R4300: case CPU_5KC: case CPU_TX49XX: case CPU_PR4450: @@ -604,13 +603,12 @@ void build_tlb_write_entry(u32 **p, struct uasm_label **l, case CPU_VR4131: case CPU_VR4133: - case CPU_R5432: uasm_i_nop(p); uasm_i_nop(p); tlbw(p); break; - case CPU_JZRISC: + case CPU_XBURST: tlbw(p); uasm_i_nop(p); break; @@ -631,7 +629,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, return; } - if (cpu_has_rixi && _PAGE_NO_EXEC) { + if (cpu_has_rixi && !!_PAGE_NO_EXEC) { if (fill_includes_sw_bits) { UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); } else { @@ -2609,21 +2607,11 @@ void build_tlb_refill_handler(void) check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3); #endif - switch (current_cpu_type()) { - case CPU_R2000: - case CPU_R3000: - case CPU_R3000A: - case CPU_R3081E: - case CPU_TX3912: - case CPU_TX3922: - case CPU_TX3927: + if (cpu_has_3kex) { #ifndef CONFIG_MIPS_PGD_C0_CONTEXT - if (cpu_has_local_ebase) - build_r3000_tlb_refill_handler(); if (!run_once) { - if (!cpu_has_local_ebase) - build_r3000_tlb_refill_handler(); build_setup_pgd(); + build_r3000_tlb_refill_handler(); build_r3000_tlb_load_handler(); build_r3000_tlb_store_handler(); build_r3000_tlb_modify_handler(); @@ -2633,34 +2621,27 @@ void build_tlb_refill_handler(void) #else panic("No R3000 TLB refill handler"); #endif - break; + return; + } - case CPU_R8000: - panic("No R8000 TLB refill handler yet"); - break; + if (cpu_has_ldpte) + setup_pw(); - default: + if (!run_once) { + scratch_reg = allocate_kscratch(); + build_setup_pgd(); + build_r4000_tlb_load_handler(); + build_r4000_tlb_store_handler(); + build_r4000_tlb_modify_handler(); if (cpu_has_ldpte) - setup_pw(); - - if (!run_once) { - scratch_reg = allocate_kscratch(); - build_setup_pgd(); - build_r4000_tlb_load_handler(); - build_r4000_tlb_store_handler(); - build_r4000_tlb_modify_handler(); - if (cpu_has_ldpte) - build_loongson3_tlb_refill_handler(); - else if (!cpu_has_local_ebase) - build_r4000_tlb_refill_handler(); - flush_tlb_handlers(); - run_once++; - } - if (cpu_has_local_ebase) + build_loongson3_tlb_refill_handler(); + else build_r4000_tlb_refill_handler(); - if (cpu_has_xpa) - config_xpa_params(); - if (cpu_has_htw) - config_htw_params(); + flush_tlb_handlers(); + run_once++; } + if (cpu_has_xpa) + config_xpa_params(); + if (cpu_has_htw) + config_htw_params(); } diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c index 868921adef1d..7c25a0a2345c 100644 --- a/arch/mips/mti-malta/malta-memory.c +++ b/arch/mips/mti-malta/malta-memory.c @@ -39,17 +39,6 @@ void __init fw_meminit(void) void __init prom_free_prom_memory(void) { - unsigned long addr; - int i; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) - continue; - - addr = boot_mem_map.map[i].addr; - free_init_pages("YAMON memory", - addr, addr + boot_mem_map.map[i].size); - } } phys_addr_t mips_cdmm_phys_base(void) diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index f743fd9da323..1a0fc5b62ba4 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -34,6 +34,7 @@ #include <linux/kernel.h> #include <linux/of_fdt.h> +#include <linux/memblock.h> #include <asm/idle.h> #include <asm/reboot.h> @@ -67,12 +68,11 @@ static void nlm_linux_exit(void) static void nlm_fixup_mem(void) { const int pref_backup = 512; - int i; + struct memblock_region *mem; - for (i = 0; i < boot_mem_map.nr_map; i++) { - if (boot_mem_map.map[i].type != BOOT_MEM_RAM) - continue; - boot_mem_map.map[i].size -= pref_backup; + for_each_memblock(memory, mem) { + memblock_remove(mem->base + mem->size - pref_backup, + pref_backup); } } @@ -110,7 +110,7 @@ void __init plat_mem_setup(void) /* memory and bootargs from DT */ xlp_early_init_devtree(); - if (boot_mem_map.nr_map == 0) { + if (memblock_end_of_DRAM() == 0) { pr_info("Using DRAM BARs for memory map.\n"); xlp_init_mem_from_bars(); } diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c index bcf7f559789a..7b4d40354ee7 100644 --- a/arch/mips/pci/pci-xtalk-bridge.c +++ b/arch/mips/pci/pci-xtalk-bridge.c @@ -20,16 +20,50 @@ * Most of the IOC3 PCI config register aren't present * we emulate what is needed for a normal PCI enumeration */ -static u32 emulate_ioc3_cfg(int where, int size) +static int ioc3_cfg_rd(void *addr, int where, int size, u32 *value) { - if (size == 1 && where == 0x3d) - return 0x01; - else if (size == 2 && where == 0x3c) - return 0x0100; - else if (size == 4 && where == 0x3c) - return 0x00000100; + u32 cf, shift, mask; - return 0; + switch (where & ~3) { + case 0x00 ... 0x10: + case 0x40 ... 0x44: + if (get_dbe(cf, (u32 *)addr)) + return PCIBIOS_DEVICE_NOT_FOUND; + break; + case 0x3c: + /* emulate sane interrupt pin value */ + cf = 0x00000100; + break; + default: + cf = 0; + break; + } + shift = (where & 3) << 3; + mask = 0xffffffffU >> ((4 - size) << 3); + *value = (cf >> shift) & mask; + + return PCIBIOS_SUCCESSFUL; +} + +static int ioc3_cfg_wr(void *addr, int where, int size, u32 value) +{ + u32 cf, shift, mask, smask; + + if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) + return PCIBIOS_SUCCESSFUL; + + if (get_dbe(cf, (u32 *)addr)) + return PCIBIOS_DEVICE_NOT_FOUND; + + shift = ((where & 3) << 3); + mask = (0xffffffffU >> ((4 - size) << 3)); + smask = mask << shift; + + cf = (cf & ~smask) | ((value & mask) << shift); + if (put_dbe(cf, (u32 *)addr)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; } static void bridge_disable_swapping(struct pci_dev *dev) @@ -64,7 +98,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, int slot = PCI_SLOT(devfn); int fn = PCI_FUNC(devfn); void *addr; - u32 cf, shift, mask; + u32 cf; int res; addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID]; @@ -75,8 +109,10 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, * 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 is_ioc3; + if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) { + addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; + return ioc3_cfg_rd(addr, where, size, value); + } addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; @@ -88,26 +124,6 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, res = get_dbe(*value, (u32 *)addr); return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; - -is_ioc3: - - /* - * IOC3 special handling - */ - if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { - *value = emulate_ioc3_cfg(where, size); - return PCIBIOS_SUCCESSFUL; - } - - addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; - if (get_dbe(cf, (u32 *)addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - shift = ((where & 3) << 3); - mask = (0xffffffffU >> ((4 - size) << 3)); - *value = (cf >> shift) & mask; - - return PCIBIOS_SUCCESSFUL; } static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, @@ -119,7 +135,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, int slot = PCI_SLOT(devfn); int fn = PCI_FUNC(devfn); void *addr; - u32 cf, shift, mask; + u32 cf; int res; bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); @@ -131,8 +147,10 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, * 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 is_ioc3; + if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) { + addr = &bridge->b_type1_cfg.c[(fn << 8) | (where & ~3)]; + return ioc3_cfg_rd(addr, where, size, value); + } addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; @@ -144,26 +162,6 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, res = get_dbe(*value, (u32 *)addr); return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; - -is_ioc3: - - /* - * IOC3 special handling - */ - if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { - *value = emulate_ioc3_cfg(where, size); - return PCIBIOS_SUCCESSFUL; - } - - addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; - if (get_dbe(cf, (u32 *)addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - shift = ((where & 3) << 3); - mask = (0xffffffffU >> ((4 - size) << 3)); - *value = (cf >> shift) & mask; - - return PCIBIOS_SUCCESSFUL; } static int pci_read_config(struct pci_bus *bus, unsigned int devfn, @@ -183,7 +181,7 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, int slot = PCI_SLOT(devfn); int fn = PCI_FUNC(devfn); void *addr; - u32 cf, shift, mask, smask; + u32 cf; int res; addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID]; @@ -194,8 +192,10 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, * 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 is_ioc3; + if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) { + addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; + return ioc3_cfg_wr(addr, where, size, value); + } addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; @@ -210,29 +210,6 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_SUCCESSFUL; - -is_ioc3: - - /* - * IOC3 special handling - */ - if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) - return PCIBIOS_SUCCESSFUL; - - addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; - - if (get_dbe(cf, (u32 *)addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - shift = ((where & 3) << 3); - mask = (0xffffffffU >> ((4 - size) << 3)); - smask = mask << shift; - - cf = (cf & ~smask) | ((value & mask) << shift); - if (put_dbe(cf, (u32 *)addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - return PCIBIOS_SUCCESSFUL; } static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, @@ -244,7 +221,7 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, int fn = PCI_FUNC(devfn); int busno = bus->number; void *addr; - u32 cf, shift, mask, smask; + u32 cf; int res; bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); @@ -256,8 +233,10 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, * 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 is_ioc3; + if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) { + addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; + return ioc3_cfg_wr(addr, where, size, value); + } addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; @@ -272,28 +251,6 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_SUCCESSFUL; - -is_ioc3: - - /* - * IOC3 special handling - */ - if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) - return PCIBIOS_SUCCESSFUL; - - addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; - if (get_dbe(cf, (u32 *)addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - shift = ((where & 3) << 3); - mask = (0xffffffffU >> ((4 - size) << 3)); - smask = mask << shift; - - cf = (cf & ~smask) | ((value & mask) << shift); - if (put_dbe(cf, (u32 *)addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - return PCIBIOS_SUCCESSFUL; } static int pci_write_config(struct pci_bus *bus, unsigned int devfn, diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c index 6fdcb3d6fbb5..dfb527961a27 100644 --- a/arch/mips/pmcs-msp71xx/msp_prom.c +++ b/arch/mips/pmcs-msp71xx/msp_prom.c @@ -61,6 +61,10 @@ int init_debug = 1; /* memory blocks */ struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; +static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata; +static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata; +static unsigned int nr_prom_mem __initdata; + /* default feature sets */ static char msp_default_features[] = #if defined(CONFIG_PMC_MSP4200_EVAL) \ @@ -352,6 +356,16 @@ void __init prom_meminit(void) add_memory_region(base, size, type); p++; + + if (type == BOOT_MEM_ROM_DATA) { + if (nr_prom_mem >= 5) { + pr_err("Too many ROM DATA regions"); + continue; + } + prom_mem_base[nr_prom_mem] = base; + prom_mem_size[nr_prom_mem] = size; + nr_prom_mem++; + } } } @@ -407,13 +421,9 @@ void __init prom_free_prom_memory(void) envp[i] = NULL; /* end array with null pointer */ prom_envp = envp; - for (i = 0; i < boot_mem_map.nr_map; i++) { - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) - continue; - - addr = boot_mem_map.map[i].addr; + for (i = 0; i < nr_prom_mem; i++) { free_init_pages("prom memory", - addr, addr + boot_mem_map.map[i].size); + prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]); } } diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 49c22ddd9c41..1434fa60f3db 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -51,7 +51,6 @@ choice select MIPS_GIC select COMMON_CLK select CLKSRC_MIPS_GIC - select HAVE_PCI endchoice choice diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c index 0ad8ff2e4f6e..652424d8ed51 100644 --- a/arch/mips/ralink/timer.c +++ b/arch/mips/ralink/timer.c @@ -106,10 +106,8 @@ static int rt_timer_probe(struct platform_device *pdev) } rt->irq = platform_get_irq(pdev, 0); - if (rt->irq < 0) { - dev_err(&pdev->dev, "failed to load irq\n"); + if (rt->irq < 0) return rt->irq; - } rt->membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rt->membase)) diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c index c0cf7baee36d..c61362d9ea95 100644 --- a/arch/mips/sgi-ip22/ip28-berr.c +++ b/arch/mips/sgi-ip22/ip28-berr.c @@ -8,6 +8,7 @@ #include <linux/init.h> #include <linux/kernel.h> +#include <linux/mm.h> #include <linux/sched.h> #include <linux/sched/debug.h> #include <linux/sched/signal.h> @@ -300,23 +301,6 @@ static void print_buserr(const struct pt_regs *regs) field, regs->cp0_epc, field, regs->regs[31]); } -/* - * Check, whether MC's (virtual) DMA address caused the bus error. - * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI - */ - -static int addr_is_ram(unsigned long addr, unsigned sz) -{ - int i; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long a = boot_mem_map.map[i].addr; - if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size) - return 1; - } - return 0; -} - static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr) { /* This is likely rather similar to correct code ;-) */ @@ -331,7 +315,7 @@ static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr) /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */ unsigned long pte = (lo >> 6) << 12; /* PTEBase */ pte += 8*((vaddr >> pgsz) & 0x1ff); - if (addr_is_ram(pte, 8)) { + if (page_is_ram(PFN_DOWN(pte))) { /* * Note: Since DMA hardware does look up * translation on its own, this PTE *must* diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index 7221df24cb23..69cfa0a5339e 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -1,6 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 # Objects to go into the VDSO. -obj-vdso-y := elf.o gettimeofday.o sigreturn.o + +# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before +# the inclusion of generic Makefile. +ARCH_REL_TYPE_ABS := R_MIPS_JUMP_SLOT|R_MIPS_GLOB_DAT +include $(srctree)/lib/vdso/Makefile + +obj-vdso-y := elf.o vgettimeofday.o sigreturn.o # Common compiler flags between ABIs. ccflags-vdso := \ @@ -15,15 +21,31 @@ ifdef CONFIG_CC_IS_CLANG ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS)) endif +# +# The -fno-jump-tables flag only prevents the compiler from generating +# jump tables but does not prevent the compiler from emitting absolute +# offsets. cflags-vdso := $(ccflags-vdso) \ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ - -O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ - -DDISABLE_BRANCH_PROFILING \ + -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ + -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ $(call cc-option, -fno-asynchronous-unwind-tables) \ $(call cc-option, -fno-stack-protector) aflags-vdso := $(ccflags-vdso) \ -D__ASSEMBLY__ -Wa,-gdwarf-2 +ifneq ($(c-gettimeofday-y),) +CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y) + +# config-n32-o32-env.c prepares the environment to build a 32bit vDSO +# library on a 64bit kernel. +# Note: Needs to be included before than the generic library. +CFLAGS_vgettimeofday-o32.o = -include $(srctree)/$(src)/config-n32-o32-env.c -include $(c-gettimeofday-y) +CFLAGS_vgettimeofday-n32.o = -include $(srctree)/$(src)/config-n32-o32-env.c -include $(c-gettimeofday-y) +endif + +CFLAGS_REMOVE_vgettimeofday.o = -pg + # # For the pre-R6 code in arch/mips/vdso/vdso.h for locating # the base address of VDSO, the linker will emit a R_MIPS_PC32 @@ -48,6 +70,8 @@ VDSO_LDFLAGS := \ $(addprefix -Wl$(comma),$(filter -E%,$(KBUILD_CFLAGS))) \ -nostdlib -shared -Wl,--hash-style=sysv -Wl,--build-id +CFLAGS_REMOVE_vdso.o = -pg + GCOV_PROFILE := n UBSAN_SANITIZE := n @@ -55,11 +79,14 @@ UBSAN_SANITIZE := n # Shared build commands. # +quiet_cmd_vdsold_and_vdso_check = LD $@ + cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check) + quiet_cmd_vdsold = VDSO $@ cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \ -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ -quiet_cmd_vdsoas_o_S = AS $@ +quiet_cmd_vdsoas_o_S = AS $@ cmd_vdsoas_o_S = $(CC) $(a_flags) -c -o $@ $< # Strip rule for the raw .so files @@ -95,7 +122,7 @@ $(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi) $(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi) $(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE - $(call if_changed,vdsold) + $(call if_changed,vdsold_and_vdso_check) $(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \ $(obj)/genvdso FORCE @@ -133,7 +160,7 @@ $(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE $(call if_changed_dep,cpp_lds_S) $(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE - $(call if_changed,vdsold) + $(call if_changed,vdsold_and_vdso_check) $(obj)/vdso-o32-image.c: VDSO_NAME := o32 $(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \ @@ -173,7 +200,7 @@ $(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE $(call if_changed_dep,cpp_lds_S) $(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE - $(call if_changed,vdsold) + $(call if_changed,vdsold_and_vdso_check) $(obj)/vdso-n32-image.c: VDSO_NAME := n32 $(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \ diff --git a/arch/mips/vdso/config-n32-o32-env.c b/arch/mips/vdso/config-n32-o32-env.c new file mode 100644 index 000000000000..0011a632aef2 --- /dev/null +++ b/arch/mips/vdso/config-n32-o32-env.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Configuration file for O32 and N32 binaries. + * Note: To be included before lib/vdso/gettimeofday.c + */ +#if defined(CONFIG_MIPS32_O32) || defined(CONFIG_MIPS32_N32) +/* + * In case of a 32 bit VDSO for a 64 bit kernel fake a 32 bit kernel + * configuration. + */ +#undef CONFIG_64BIT + +#define BUILD_VDSO32 +#define CONFIG_32BIT 1 +#define CONFIG_GENERIC_ATOMIC64 1 +#define BUILD_VDSO32_64 + +#endif + diff --git a/arch/mips/vdso/elf.S b/arch/mips/vdso/elf.S index e7543e8f426c..a25cb147f1ca 100644 --- a/arch/mips/vdso/elf.S +++ b/arch/mips/vdso/elf.S @@ -4,7 +4,7 @@ * Author: Alex Smith <alex.smith@imgtec.com> */ -#include "vdso.h" +#include <asm/vdso/vdso.h> #include <asm/isa-rev.h> diff --git a/arch/mips/vdso/sigreturn.S b/arch/mips/vdso/sigreturn.S index c3597632874b..e5c0ab98ab46 100644 --- a/arch/mips/vdso/sigreturn.S +++ b/arch/mips/vdso/sigreturn.S @@ -4,7 +4,7 @@ * Author: Alex Smith <alex.smith@imgtec.com> */ -#include "vdso.h" +#include <asm/vdso/vdso.h> #include <uapi/asm/unistd.h> diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S index 94d90c440590..da4627430aba 100644 --- a/arch/mips/vdso/vdso.lds.S +++ b/arch/mips/vdso/vdso.lds.S @@ -95,6 +95,10 @@ VERSION global: __vdso_clock_gettime; __vdso_gettimeofday; + __vdso_clock_getres; +#if _MIPS_SIM != _MIPS_SIM_ABI64 + __vdso_clock_gettime64; +#endif #endif local: *; }; diff --git a/arch/mips/vdso/vgettimeofday.c b/arch/mips/vdso/vgettimeofday.c new file mode 100644 index 000000000000..6ebdc37c89fc --- /dev/null +++ b/arch/mips/vdso/vgettimeofday.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * MIPS64 and compat userspace implementations of gettimeofday() + * and similar. + * + * Copyright (C) 2015 Imagination Technologies + * Copyright (C) 2018 ARM Limited + * + */ +#include <linux/time.h> +#include <linux/types.h> + +#if _MIPS_SIM != _MIPS_SIM_ABI64 +int __vdso_clock_gettime(clockid_t clock, + struct old_timespec32 *ts) +{ + return __cvdso_clock_gettime32(clock, ts); +} + +int __vdso_gettimeofday(struct __kernel_old_timeval *tv, + struct timezone *tz) +{ + return __cvdso_gettimeofday(tv, tz); +} + +int __vdso_clock_getres(clockid_t clock_id, + struct old_timespec32 *res) +{ + return __cvdso_clock_getres_time32(clock_id, res); +} + +int __vdso_clock_gettime64(clockid_t clock, + struct __kernel_timespec *ts) +{ + return __cvdso_clock_gettime(clock, ts); +} + +#else + +int __vdso_clock_gettime(clockid_t clock, + struct __kernel_timespec *ts) +{ + return __cvdso_clock_gettime(clock, ts); +} + +int __vdso_gettimeofday(struct __kernel_old_timeval *tv, + struct timezone *tz) +{ + return __cvdso_gettimeofday(tv, tz); +} + +int __vdso_clock_getres(clockid_t clock_id, + struct __kernel_timespec *res) +{ + return __cvdso_clock_getres(clock_id, res); +} + +#endif |