aboutsummaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig96
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/Makefile9
-rw-r--r--arch/arm/boot/compressed/Makefile6
-rw-r--r--arch/arm/boot/compressed/misc.c7
-rw-r--r--arch/arm/boot/dts/Makefile1
-rw-r--r--arch/arm/boot/dts/am335x-wega.dtsi2
-rw-r--r--arch/arm/boot/dts/am43x-epos-evm.dts2
-rw-r--r--arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi2
-rw-r--r--arch/arm/boot/dts/bcm2711.dtsi1
-rw-r--r--arch/arm/boot/dts/dra7-l4.dtsi5
-rw-r--r--arch/arm/boot/dts/dra7.dtsi28
-rw-r--r--arch/arm/boot/dts/imx23-evk.dts1
-rw-r--r--arch/arm/boot/dts/imx6qdl-udoo.dtsi5
-rw-r--r--arch/arm/boot/dts/imx7ulp.dtsi2
-rw-r--r--arch/arm/boot/dts/meson.dtsi8
-rw-r--r--arch/arm/boot/dts/meson8.dtsi24
-rw-r--r--arch/arm/boot/dts/meson8b.dtsi24
-rw-r--r--arch/arm/boot/dts/omap3-beagle-ab4.dts47
-rw-r--r--arch/arm/boot/dts/omap3-beagle.dts33
-rw-r--r--arch/arm/boot/dts/omap3-devkit8000-common.dtsi18
-rw-r--r--arch/arm/boot/dts/omap3-devkit8000.dts33
-rw-r--r--arch/arm/boot/dts/rk322x.dtsi4
-rw-r--r--arch/arm/boot/dts/rk3288.dtsi2
-rw-r--r--arch/arm/boot/dts/spear320-hmi.dts1
-rw-r--r--arch/arm/boot/dts/ste-ux500-samsung-skomer.dts4
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-big-fhd.dts10
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-big.dts15
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-blaze.dts15
-rw-r--r--arch/arm/boot/dts/tegra124-venice2.dts14
-rw-r--r--arch/arm/configs/davinci_all_defconfig1
-rw-r--r--arch/arm/configs/exynos_defconfig1
-rw-r--r--arch/arm/configs/ezx_defconfig1
-rw-r--r--arch/arm/configs/imote2_defconfig1
-rw-r--r--arch/arm/configs/imxrt_defconfig35
-rw-r--r--arch/arm/configs/integrator_defconfig1
-rw-r--r--arch/arm/configs/iop32x_defconfig1
-rw-r--r--arch/arm/configs/keystone_defconfig1
-rw-r--r--arch/arm/configs/lart_defconfig1
-rw-r--r--arch/arm/configs/multi_v5_defconfig26
-rw-r--r--arch/arm/configs/multi_v7_defconfig63
-rw-r--r--arch/arm/configs/netwinder_defconfig1
-rw-r--r--arch/arm/configs/pxa_defconfig3
-rw-r--r--arch/arm/configs/sama7_defconfig31
-rw-r--r--arch/arm/configs/shmobile_defconfig4
-rw-r--r--arch/arm/configs/versatile_defconfig1
-rw-r--r--arch/arm/configs/viper_defconfig1
-rw-r--r--arch/arm/configs/zeus_defconfig1
-rw-r--r--arch/arm/crypto/aes-neonbs-core.S105
-rw-r--r--arch/arm/crypto/aes-neonbs-glue.c35
-rw-r--r--arch/arm/include/asm/assembler.h214
-rw-r--r--arch/arm/include/asm/cacheflush.h12
-rw-r--r--arch/arm/include/asm/current.h46
-rw-r--r--arch/arm/include/asm/elf.h3
-rw-r--r--arch/arm/include/asm/entry-macro-multi.S40
-rw-r--r--arch/arm/include/asm/ftrace.h4
-rw-r--r--arch/arm/include/asm/hardware/entry-macro-iomd.S131
-rw-r--r--arch/arm/include/asm/insn.h17
-rw-r--r--arch/arm/include/asm/irq.h1
-rw-r--r--arch/arm/include/asm/mach/arch.h2
-rw-r--r--arch/arm/include/asm/mmu.h2
-rw-r--r--arch/arm/include/asm/mmu_context.h22
-rw-r--r--arch/arm/include/asm/page.h3
-rw-r--r--arch/arm/include/asm/paravirt_api_clock.h1
-rw-r--r--arch/arm/include/asm/percpu.h35
-rw-r--r--arch/arm/include/asm/pgtable-2level.h2
-rw-r--r--arch/arm/include/asm/smp.h5
-rw-r--r--arch/arm/include/asm/spectre.h38
-rw-r--r--arch/arm/include/asm/stacktrace.h5
-rw-r--r--arch/arm/include/asm/switch_to.h3
-rw-r--r--arch/arm/include/asm/thread_info.h35
-rw-r--r--arch/arm/include/asm/tls.h31
-rw-r--r--arch/arm/include/asm/uaccess.h22
-rw-r--r--arch/arm/include/asm/v7m.h3
-rw-r--r--arch/arm/include/asm/vmlinux.lds.h43
-rw-r--r--arch/arm/include/asm/xor.h42
-rw-r--r--arch/arm/include/uapi/asm/signal.h2
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/asm-offsets.c3
-rw-r--r--arch/arm/kernel/entry-armv.S262
-rw-r--r--arch/arm/kernel/entry-common.S40
-rw-r--r--arch/arm/kernel/entry-ftrace.S128
-rw-r--r--arch/arm/kernel/entry-header.S47
-rw-r--r--arch/arm/kernel/entry-v7m.S39
-rw-r--r--arch/arm/kernel/ftrace.c62
-rw-r--r--arch/arm/kernel/head-common.S4
-rw-r--r--arch/arm/kernel/head.S7
-rw-r--r--arch/arm/kernel/irq.c61
-rw-r--r--arch/arm/kernel/kgdb.c36
-rw-r--r--arch/arm/kernel/module.c90
-rw-r--r--arch/arm/kernel/process.c7
-rw-r--r--arch/arm/kernel/return_address.c3
-rw-r--r--arch/arm/kernel/setup.c8
-rw-r--r--arch/arm/kernel/sleep.S13
-rw-r--r--arch/arm/kernel/smp.c11
-rw-r--r--arch/arm/kernel/spectre.c71
-rw-r--r--arch/arm/kernel/stacktrace.c3
-rw-r--r--arch/arm/kernel/swp_emulate.c2
-rw-r--r--arch/arm/kernel/traps.c158
-rw-r--r--arch/arm/kernel/unwind.c64
-rw-r--r--arch/arm/kernel/vmlinux.lds.S4
-rw-r--r--arch/arm/lib/backtrace-clang.S14
-rw-r--r--arch/arm/lib/backtrace.S8
-rw-r--r--arch/arm/lib/call_with_stack.S33
-rw-r--r--arch/arm/lib/copy_from_user.S13
-rw-r--r--arch/arm/lib/copy_template.S67
-rw-r--r--arch/arm/lib/copy_to_user.S13
-rw-r--r--arch/arm/lib/memcpy.S13
-rw-r--r--arch/arm/lib/memmove.S60
-rw-r--r--arch/arm/lib/memset.S7
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c10
-rw-r--r--arch/arm/lib/xor-neon.c12
-rw-r--r--arch/arm/mach-at91/Kconfig1
-rw-r--r--arch/arm/mach-at91/pm.c27
-rw-r--r--arch/arm/mach-at91/pm_suspend.S4
-rw-r--r--arch/arm/mach-bcm/Kconfig1
-rw-r--r--arch/arm/mach-bcm/Makefile1
-rw-r--r--arch/arm/mach-dove/irq.c6
-rw-r--r--arch/arm/mach-exynos/firmware.c4
-rw-r--r--arch/arm/mach-exynos/mcpm-exynos.c6
-rw-r--r--arch/arm/mach-footbridge/common.c87
-rw-r--r--arch/arm/mach-footbridge/include/mach/entry-macro.S107
-rw-r--r--arch/arm/mach-footbridge/include/mach/hardware.h20
-rw-r--r--arch/arm/mach-footbridge/include/mach/io.h20
-rw-r--r--arch/arm/mach-imx/Kconfig7
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/mach-imxrt.c19
-rw-r--r--arch/arm/mach-integrator/Kconfig37
-rw-r--r--arch/arm/mach-integrator/hardware.h5
-rw-r--r--arch/arm/mach-iop32x/cp6.c10
-rw-r--r--arch/arm/mach-iop32x/include/mach/entry-macro.S31
-rw-r--r--arch/arm/mach-iop32x/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-iop32x/iop3xx.h1
-rw-r--r--arch/arm/mach-iop32x/irq.c29
-rw-r--r--arch/arm/mach-iop32x/irqs.h60
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig57
-rw-r--r--arch/arm/mach-ixp4xx/Makefile19
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c451
-rw-r--r--arch/arm/mach-ixp4xx/common.c448
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-pci.c61
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-setup.c113
-rw-r--r--arch/arm/mach-ixp4xx/goramo_mlr.c532
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/hardware.h32
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/io.h545
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h303
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/platform.h102
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/udc.h8
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/uncompress.h4
-rw-r--r--arch/arm/mach-ixp4xx/irqs.h64
-rw-r--r--arch/arm/mach-mmp/sram.c22
-rw-r--r--arch/arm/mach-mstar/Kconfig2
-rw-r--r--arch/arm/mach-mv78xx0/irq.c3
-rw-r--r--arch/arm/mach-nspire/Kconfig1
-rw-r--r--arch/arm/mach-omap2/display.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c4
-rw-r--r--arch/arm/mach-orion5x/Kconfig2
-rw-r--r--arch/arm/mach-orion5x/irq.c2
-rw-r--r--arch/arm/mach-pxa/Kconfig10
-rw-r--r--arch/arm/mach-pxa/Makefile2
-rw-r--r--arch/arm/mach-pxa/corgi.c26
-rw-r--r--arch/arm/mach-pxa/hx4700.c10
-rw-r--r--arch/arm/mach-pxa/icontrol.c26
-rw-r--r--arch/arm/mach-pxa/include/mach/uncompress.h5
-rw-r--r--arch/arm/mach-pxa/littleton.c10
-rw-r--r--arch/arm/mach-pxa/magician.c12
-rw-r--r--arch/arm/mach-pxa/poodle.c14
-rw-r--r--arch/arm/mach-pxa/spitz.c26
-rw-r--r--arch/arm/mach-pxa/stargate2.c1030
-rw-r--r--arch/arm/mach-pxa/z2.c20
-rw-r--r--arch/arm/mach-qcom/platsmp.c3
-rw-r--r--arch/arm/mach-rpc/fiq.S5
-rw-r--r--arch/arm/mach-rpc/include/mach/entry-macro.S13
-rw-r--r--arch/arm/mach-rpc/irq.c95
-rw-r--r--arch/arm/mach-s3c/Kconfig12
-rw-r--r--arch/arm/mach-s3c/devs.c77
-rw-r--r--arch/arm/mach-s3c/mach-crag6410-module.c13
-rw-r--r--arch/arm/mach-s3c/mach-crag6410.c13
-rw-r--r--arch/arm/mach-s3c/setup-spi-s3c64xx.c9
-rw-r--r--arch/arm/mach-s3c/spi-core-s3c24xx.h6
-rw-r--r--arch/arm/mach-shmobile/Kconfig2
-rw-r--r--arch/arm/mach-socfpga/Kconfig2
-rw-r--r--arch/arm/mach-spear/spear13xx.c2
-rw-r--r--arch/arm/mach-ux500/Kconfig2
-rw-r--r--arch/arm/mm/Kconfig12
-rw-r--r--arch/arm/mm/cache-v7.S40
-rw-r--r--arch/arm/mm/context.c3
-rw-r--r--arch/arm/mm/init.c43
-rw-r--r--arch/arm/mm/ioremap.c18
-rw-r--r--arch/arm/mm/mmu.c2
-rw-r--r--arch/arm/mm/proc-v7-bugs.c208
-rw-r--r--arch/arm/plat-orion/gpio.c8
-rw-r--r--arch/arm/plat-orion/include/plat/orion-gpio.h3
-rw-r--r--arch/arm/probes/kprobes/actions-common.c8
-rw-r--r--arch/arm/probes/kprobes/actions-thumb.c16
-rw-r--r--arch/arm/vdso/Makefile2
195 files changed, 2608 insertions, 5339 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 160881d7c5d0..c1251856ef77 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,6 +5,7 @@ config ARM
select ARCH_32BIT_OFF_T
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
select ARCH_HAS_BINFMT_FLAT
+ select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
select ARCH_HAS_ELF_RANDOMIZE
@@ -37,6 +38,7 @@ config ARM
select ARCH_USE_CMPXCHG_LOCKREF
select ARCH_USE_MEMTEST
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
+ select ARCH_WANT_GENERAL_HUGETLB
select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_WANT_LD_ORPHAN_WARN
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
@@ -58,6 +60,7 @@ config ARM
select GENERIC_CPU_AUTOPROBE
select GENERIC_EARLY_IOREMAP
select GENERIC_IDLE_POLL_SETUP
+ select GENERIC_IRQ_MULTI_HANDLER
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_SHOW_LEVEL
@@ -92,8 +95,8 @@ config ARM
select HAVE_EXIT_THREAD
select HAVE_FAST_GUP if ARM_LPAE
select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
- select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG
- select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !(THUMB2_KERNEL && CC_IS_CLANG)
+ select HAVE_FUNCTION_GRAPH_TRACER
+ select HAVE_FUNCTION_TRACER if !XIP_KERNEL
select HAVE_GCC_PLUGINS
select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
select HAVE_IRQ_TIME_ACCOUNTING
@@ -127,7 +130,8 @@ config ARM
select PERF_USE_VMALLOC
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
- select THREAD_INFO_IN_TASK if CURRENT_POINTER_IN_TPIDRURO
+ select THREAD_INFO_IN_TASK
+ select HAVE_ARCH_VMAP_STACK if MMU && ARM_HAS_GROUP_RELOCS
select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
# Above selects are sorted alphabetically; please add new ones
# according to that. Thanks.
@@ -139,6 +143,17 @@ config ARM
Europe. There is an ARM Linux project with a web page at
<http://www.arm.linux.org.uk/>.
+config ARM_HAS_GROUP_RELOCS
+ def_bool y
+ depends on !LD_IS_LLD || LLD_VERSION >= 140000
+ depends on !COMPILE_TEST
+ help
+ Whether or not to use R_ARM_ALU_PC_Gn or R_ARM_LDR_PC_Gn group
+ relocations, which have been around for a long time, but were not
+ supported in LLD until version 14. The combined range is -/+ 256 MiB,
+ which is usually sufficient, but not for allyesconfig, so we disable
+ this feature when doing compile testing.
+
config ARM_HAS_SG_CHAIN
bool
@@ -218,18 +233,12 @@ config ARCH_MAY_HAVE_PC_FDC
config ARCH_SUPPORTS_UPROBES
def_bool y
-config ARCH_HAS_DMA_SET_COHERENT_MASK
- bool
-
config GENERIC_ISA_DMA
bool
config FIQ
bool
-config NEED_RET_TO_USER
- bool
-
config ARCH_MTD_XIP
bool
@@ -267,7 +276,7 @@ config PHYS_OFFSET
hex "Physical address of main memory" if MMU
depends on !ARM_PATCH_PHYS_VIRT
default DRAM_BASE if !MMU
- default 0x00000000 if ARCH_FOOTBRIDGE || ARCH_IXP4XX
+ default 0x00000000 if ARCH_FOOTBRIDGE
default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
default 0x30000000 if ARCH_S3C24XX
default 0xa0000000 if ARCH_IOP32X || ARCH_PXA
@@ -295,6 +304,17 @@ config MMU
Select if you want MMU-based virtualised addressing space
support by paged memory management. If unsure, say 'Y'.
+config ARM_SINGLE_ARMV7M
+ def_bool !MMU
+ select ARM_NVIC
+ select AUTO_ZRELADDR
+ select TIMER_OF
+ select COMMON_CLK
+ select CPU_V7M
+ select NO_IOPORT_MAP
+ select SPARSE_IRQ
+ select USE_OF
+
config ARCH_MMAP_RND_BITS_MIN
default 8
@@ -309,12 +329,11 @@ config ARCH_MMAP_RND_BITS_MAX
#
choice
prompt "ARM system type"
- default ARM_SINGLE_ARMV7M if !MMU
- default ARCH_MULTIPLATFORM if MMU
+ depends on MMU
+ default ARCH_MULTIPLATFORM
config ARCH_MULTIPLATFORM
bool "Allow multiple platforms to be selected"
- depends on MMU
select ARCH_FLATMEM_ENABLE
select ARCH_SPARSEMEM_ENABLE
select ARCH_SELECT_MEMORY_MODEL
@@ -323,31 +342,17 @@ config ARCH_MULTIPLATFORM
select AUTO_ZRELADDR
select TIMER_OF
select COMMON_CLK
- select GENERIC_IRQ_MULTI_HANDLER
select HAVE_PCI
select PCI_DOMAINS_GENERIC if PCI
select SPARSE_IRQ
select USE_OF
-config ARM_SINGLE_ARMV7M
- bool "ARMv7-M based platforms (Cortex-M0/M3/M4)"
- depends on !MMU
- select ARM_NVIC
- select AUTO_ZRELADDR
- select TIMER_OF
- select COMMON_CLK
- select CPU_V7M
- select NO_IOPORT_MAP
- select SPARSE_IRQ
- select USE_OF
-
config ARCH_EP93XX
bool "EP93xx-based"
select ARCH_SPARSEMEM_ENABLE
select ARM_AMBA
imply ARM_PATCH_PHYS_VIRT
select ARM_VIC
- select GENERIC_IRQ_MULTI_HANDLER
select AUTO_ZRELADDR
select CLKSRC_MMIO
select CPU_ARM920T
@@ -360,7 +365,6 @@ config ARCH_FOOTBRIDGE
bool "FootBridge"
select CPU_SA110
select FOOTBRIDGE
- select NEED_MACH_IO_H if !MMU
select NEED_MACH_MEMORY_H
help
Support for systems based on the DC21285 companion chip
@@ -368,11 +372,9 @@ config ARCH_FOOTBRIDGE
config ARCH_IOP32X
bool "IOP32x-based"
- depends on MMU
select CPU_XSCALE
select GPIO_IOP
select GPIOLIB
- select NEED_RET_TO_USER
select FORCE_PCI
select PLAT_IOP
help
@@ -381,19 +383,15 @@ config ARCH_IOP32X
config ARCH_IXP4XX
bool "IXP4xx-based"
- depends on MMU
- select ARCH_HAS_DMA_SET_COHERENT_MASK
select ARCH_SUPPORTS_BIG_ENDIAN
+ select ARM_PATCH_PHYS_VIRT
select CPU_XSCALE
- select DMABOUNCE if PCI
- select GENERIC_IRQ_MULTI_HANDLER
select GPIO_IXP4XX
select GPIOLIB
select HAVE_PCI
select IXP4XX_IRQ
select IXP4XX_TIMER
- # With the new PCI driver this is not needed
- select NEED_MACH_IO_H if IXP4XX_PCI_LEGACY
+ select SPARSE_IRQ
select USB_EHCI_BIG_ENDIAN_DESC
select USB_EHCI_BIG_ENDIAN_MMIO
help
@@ -402,7 +400,6 @@ config ARCH_IXP4XX
config ARCH_DOVE
bool "Marvell Dove"
select CPU_PJ4
- select GENERIC_IRQ_MULTI_HANDLER
select GPIOLIB
select HAVE_PCI
select MVEBU_MBUS
@@ -416,7 +413,6 @@ config ARCH_DOVE
config ARCH_PXA
bool "PXA2xx/PXA3xx-based"
- depends on MMU
select ARCH_MTD_XIP
select ARM_CPU_SUSPEND if PM
select AUTO_ZRELADDR
@@ -425,7 +421,6 @@ config ARCH_PXA
select CLKSRC_MMIO
select TIMER_OF
select CPU_XSCALE if !CPU_XSC3
- select GENERIC_IRQ_MULTI_HANDLER
select GPIO_PXA
select GPIOLIB
select IRQ_DOMAIN
@@ -436,7 +431,6 @@ config ARCH_PXA
config ARCH_RPC
bool "RiscPC"
- depends on MMU
depends on !CC_IS_CLANG && GCC_VERSION < 90100 && GCC_VERSION >= 60000
select ARCH_ACORN
select ARCH_MAY_HAVE_PC_FDC
@@ -464,7 +458,6 @@ config ARCH_SA1100
select COMMON_CLK
select CPU_FREQ
select CPU_SA1100
- select GENERIC_IRQ_MULTI_HANDLER
select GPIOLIB
select IRQ_DOMAIN
select ISA
@@ -479,7 +472,6 @@ config ARCH_S3C24XX
select CLKSRC_SAMSUNG_PWM
select GPIO_SAMSUNG
select GPIOLIB
- select GENERIC_IRQ_MULTI_HANDLER
select NEED_MACH_IO_H
select S3C2410_WATCHDOG
select SAMSUNG_ATAGS
@@ -493,11 +485,9 @@ config ARCH_S3C24XX
config ARCH_OMAP1
bool "TI OMAP1"
- depends on MMU
select ARCH_OMAP
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
- select GENERIC_IRQ_MULTI_HANDLER
select GPIOLIB
select HAVE_LEGACY_CLK
select IRQ_DOMAIN
@@ -1176,7 +1166,12 @@ config SMP_ON_UP
config CURRENT_POINTER_IN_TPIDRURO
def_bool y
- depends on SMP && CPU_32v6K && !CPU_V6
+ depends on CPU_32v6K && !CPU_V6
+
+config IRQSTACKS
+ def_bool y
+ select HAVE_IRQ_EXIT_ON_IRQ_STACK
+ select HAVE_SOFTIRQ_ON_OWN_STACK
config ARM_CPU_TOPOLOGY
bool "Support cpu topology definition"
@@ -1520,9 +1515,6 @@ config HW_PERF_EVENTS
def_bool y
depends on ARM_PMU
-config ARCH_WANT_GENERAL_HUGETLB
- def_bool y
-
config ARM_MODULE_PLTS
bool "Use PLTs to allow module memory to spill over into vmalloc area"
depends on MODULES
@@ -1620,10 +1612,14 @@ config XEN
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
+config CC_HAVE_STACKPROTECTOR_TLS
+ def_bool $(cc-option,-mtp=cp15 -mstack-protector-guard=tls -mstack-protector-guard-offset=0)
+
config STACKPROTECTOR_PER_TASK
bool "Use a unique stack canary value for each task"
- depends on GCC_PLUGINS && STACKPROTECTOR && THREAD_INFO_IN_TASK && !XIP_DEFLATED_DATA
- select GCC_PLUGIN_ARM_SSP_PER_TASK
+ depends on STACKPROTECTOR && CURRENT_POINTER_IN_TPIDRURO && !XIP_DEFLATED_DATA
+ depends on GCC_PLUGINS || CC_HAVE_STACKPROTECTOR_TLS
+ select GCC_PLUGIN_ARM_SSP_PER_TASK if !CC_HAVE_STACKPROTECTOR_TLS
default y
help
Due to the fact that GCC uses an ordinary symbol reference from
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 976315dea958..0c9497d549e3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -65,7 +65,7 @@ config UNWINDER_FRAME_POINTER
config UNWINDER_ARM
bool "ARM EABI stack unwinder"
- depends on AEABI && !FUNCTION_GRAPH_TRACER
+ depends on AEABI
select ARM_UNWIND
help
This option enables stack unwinding support in the kernel
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 34baf885573a..a2391b8de5a5 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -276,6 +276,14 @@ endif
ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y)
prepare: stack_protector_prepare
+ifeq ($(CONFIG_CC_HAVE_STACKPROTECTOR_TLS),y)
+stack_protector_prepare: prepare0
+ $(eval KBUILD_CFLAGS += \
+ -mstack-protector-guard=tls \
+ -mstack-protector-guard-offset=$(shell \
+ awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\
+ include/generated/asm-offsets.h))
+else
stack_protector_prepare: prepare0
$(eval SSP_PLUGIN_CFLAGS := \
-fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \
@@ -284,6 +292,7 @@ stack_protector_prepare: prepare0
$(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS))
$(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS))
endif
+endif
all: $(notdir $(KBUILD_IMAGE))
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 954eee8a785a..187a187706cb 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -92,17 +92,13 @@ ifeq ($(CONFIG_USE_OF),y)
OBJS += $(libfdt_objs) fdt_check_mem_start.o
endif
-# -fstack-protector-strong triggers protection checks in this code,
-# but it is being used too early to link to meaningful stack_chk logic.
-$(foreach o, $(libfdt_objs) atags_to_fdt.o fdt_check_mem_start.o, \
- $(eval CFLAGS_$(o) := -I $(srctree)/scripts/dtc/libfdt -fno-stack-protector))
-
targets := vmlinux vmlinux.lds piggy_data piggy.o \
head.o $(OBJS)
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \
+ -I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \
-I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN)
ccflags-remove-$(CONFIG_FUNCTION_TRACER) += -pg
asflags-y := -DZIMAGE
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index e1e9a5dde853..c3c66ff2d696 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -128,13 +128,6 @@ asmlinkage void __div0(void)
error("Attempting division by 0!");
}
-const unsigned long __stack_chk_guard = 0x000a0dff;
-
-void __stack_chk_fail(void)
-{
- error("stack-protector: Kernel stack is corrupted\n");
-}
-
extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index ef21d19a855c..7c16f8a2b738 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -814,6 +814,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += \
logicpd-som-lv-37xx-devkit.dtb \
omap3430-sdp.dtb \
omap3-beagle.dtb \
+ omap3-beagle-ab4.dtb \
omap3-beagle-xm.dtb \
omap3-beagle-xm-ab.dtb \
omap3-cm-t3517.dtb \
diff --git a/arch/arm/boot/dts/am335x-wega.dtsi b/arch/arm/boot/dts/am335x-wega.dtsi
index 673159d93a6a..f957fea8208e 100644
--- a/arch/arm/boot/dts/am335x-wega.dtsi
+++ b/arch/arm/boot/dts/am335x-wega.dtsi
@@ -55,7 +55,7 @@
2 1 0 0 /* # 0: INACTIVE, 1: TX, 2: RX */
>;
tx-num-evt = <16>;
- rt-num-evt = <16>;
+ rx-num-evt = <16>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index 2f4d2e4e9b3e..4f9a7251a107 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -11,7 +11,7 @@
#include <dt-bindings/pinctrl/am43xx.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pwm/pwm.h>
-#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
+#include <dt-bindings/sound/tlv320aic31xx.h>
/ {
model = "TI AM43x EPOS EVM";
diff --git a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
index 6dde51c2aed3..e4775bbceecc 100644
--- a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
@@ -118,7 +118,7 @@
};
pinctrl_fwqspid_default: fwqspid_default {
- function = "FWQSPID";
+ function = "FWSPID";
groups = "FWQSPID";
};
diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
index 0f2f26dc5ec6..89af57482bc8 100644
--- a/arch/arm/boot/dts/bcm2711.dtsi
+++ b/arch/arm/boot/dts/bcm2711.dtsi
@@ -290,6 +290,7 @@
hvs: hvs@7e400000 {
compatible = "brcm,bcm2711-hvs";
+ reg = <0x7e400000 0x8000>;
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
};
diff --git a/arch/arm/boot/dts/dra7-l4.dtsi b/arch/arm/boot/dts/dra7-l4.dtsi
index 956a26d52a4c..0a11bacffc1f 100644
--- a/arch/arm/boot/dts/dra7-l4.dtsi
+++ b/arch/arm/boot/dts/dra7-l4.dtsi
@@ -3482,8 +3482,7 @@
ti,timer-pwm;
};
};
-
- target-module@2c000 { /* 0x4882c000, ap 17 02.0 */
+ timer15_target: target-module@2c000 { /* 0x4882c000, ap 17 02.0 */
compatible = "ti,sysc-omap4-timer", "ti,sysc";
reg = <0x2c000 0x4>,
<0x2c010 0x4>;
@@ -3511,7 +3510,7 @@
};
};
- target-module@2e000 { /* 0x4882e000, ap 19 14.0 */
+ timer16_target: target-module@2e000 { /* 0x4882e000, ap 19 14.0 */
compatible = "ti,sysc-omap4-timer", "ti,sysc";
reg = <0x2e000 0x4>,
<0x2e010 0x4>;
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 6b485cbed8d5..97ce0c4f1df7 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -160,7 +160,7 @@
target-module@48210000 {
compatible = "ti,sysc-omap4-simple", "ti,sysc";
power-domains = <&prm_mpu>;
- clocks = <&mpu_clkctrl DRA7_MPU_CLKCTRL 0>;
+ clocks = <&mpu_clkctrl DRA7_MPU_MPU_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
@@ -875,10 +875,10 @@
<0x58000014 4>;
reg-names = "rev", "syss";
ti,syss-mask = <1>;
- clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 0>,
- <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 9>,
- <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 10>,
- <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 11>;
+ clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 0>,
+ <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>,
+ <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 10>,
+ <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 11>;
clock-names = "fck", "hdmi_clk", "sys_clk", "tv_clk";
#address-cells = <1>;
#size-cells = <1>;
@@ -912,7 +912,7 @@
SYSC_OMAP2_SOFTRESET |
SYSC_OMAP2_AUTOIDLE)>;
ti,syss-mask = <1>;
- clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 8>;
+ clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 8>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
@@ -939,8 +939,8 @@
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
ti,sysc-mask = <(SYSC_OMAP4_SOFTRESET)>;
- clocks = <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 9>,
- <&dss_clkctrl DRA7_DSS_CORE_CLKCTRL 8>;
+ clocks = <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 9>,
+ <&dss_clkctrl DRA7_DSS_DSS_CORE_CLKCTRL 8>;
clock-names = "fck", "dss_clk";
#address-cells = <1>;
#size-cells = <1>;
@@ -979,7 +979,7 @@
compatible = "vivante,gc";
reg = <0x0 0x700>;
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&dss_clkctrl DRA7_BB2D_CLKCTRL 0>;
+ clocks = <&dss_clkctrl DRA7_DSS_BB2D_CLKCTRL 0>;
clock-names = "core";
};
};
@@ -1333,26 +1333,26 @@
ti,no-reset-on-init;
ti,no-idle;
timer@0 {
- assigned-clocks = <&wkupaon_clkctrl DRA7_TIMER1_CLKCTRL 24>;
+ assigned-clocks = <&wkupaon_clkctrl DRA7_WKUPAON_TIMER1_CLKCTRL 24>;
assigned-clock-parents = <&sys_32k_ck>;
};
};
/* Local timers, see ARM architected timer wrap erratum i940 */
-&timer3_target {
+&timer15_target {
ti,no-reset-on-init;
ti,no-idle;
timer@0 {
- assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER3_CLKCTRL 24>;
+ assigned-clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER15_CLKCTRL 24>;
assigned-clock-parents = <&timer_sys_clk_div>;
};
};
-&timer4_target {
+&timer16_target {
ti,no-reset-on-init;
ti,no-idle;
timer@0 {
- assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER4_CLKCTRL 24>;
+ assigned-clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER16_CLKCTRL 24>;
assigned-clock-parents = <&timer_sys_clk_div>;
};
};
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
index 8cbaf1c81174..3b609d987d88 100644
--- a/arch/arm/boot/dts/imx23-evk.dts
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -79,7 +79,6 @@
MX23_PAD_LCD_RESET__GPIO_1_18
MX23_PAD_PWM3__GPIO_1_29
MX23_PAD_PWM4__GPIO_1_30
- MX23_PAD_SSP1_DETECT__SSP1_DETECT
>;
fsl,drive-strength = <MXS_DRIVE_4mA>;
fsl,voltage = <MXS_VOLTAGE_HIGH>;
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
index d07d8f83456d..ccfa8e320be6 100644
--- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
@@ -5,6 +5,8 @@
* Author: Fabio Estevam <fabio.estevam@freescale.com>
*/
+#include <dt-bindings/gpio/gpio.h>
+
/ {
aliases {
backlight = &backlight;
@@ -226,6 +228,7 @@
MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0
>;
};
@@ -304,7 +307,7 @@
&usdhc3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc3>;
- non-removable;
+ cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi
index b7ea37ad4e55..bcec98b96411 100644
--- a/arch/arm/boot/dts/imx7ulp.dtsi
+++ b/arch/arm/boot/dts/imx7ulp.dtsi
@@ -259,7 +259,7 @@
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
- assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
+ assigned-clock-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
timeout-sec = <40>;
};
diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi
index 3be7cba603d5..26eaba3fa96f 100644
--- a/arch/arm/boot/dts/meson.dtsi
+++ b/arch/arm/boot/dts/meson.dtsi
@@ -59,7 +59,7 @@
};
uart_A: serial@84c0 {
- compatible = "amlogic,meson6-uart", "amlogic,meson-uart";
+ compatible = "amlogic,meson6-uart";
reg = <0x84c0 0x18>;
interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
fifo-size = <128>;
@@ -67,7 +67,7 @@
};
uart_B: serial@84dc {
- compatible = "amlogic,meson6-uart", "amlogic,meson-uart";
+ compatible = "amlogic,meson6-uart";
reg = <0x84dc 0x18>;
interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
@@ -105,7 +105,7 @@
};
uart_C: serial@8700 {
- compatible = "amlogic,meson6-uart", "amlogic,meson-uart";
+ compatible = "amlogic,meson6-uart";
reg = <0x8700 0x18>;
interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
@@ -228,7 +228,7 @@
};
uart_AO: serial@4c0 {
- compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart";
+ compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart";
reg = <0x4c0 0x18>;
interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi
index f80ddc98d3a2..9997a5d0333a 100644
--- a/arch/arm/boot/dts/meson8.dtsi
+++ b/arch/arm/boot/dts/meson8.dtsi
@@ -736,27 +736,27 @@
};
&uart_AO {
- compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_CLK81>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8-uart", "amlogic,meson-ao-uart";
+ clocks = <&xtal>, <&clkc CLKID_CLK81>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_A {
- compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART0>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_B {
- compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART1>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_C {
- compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART2>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&usb0 {
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi
index b49b7cbaed4e..94f1c03decce 100644
--- a/arch/arm/boot/dts/meson8b.dtsi
+++ b/arch/arm/boot/dts/meson8b.dtsi
@@ -724,27 +724,27 @@
};
&uart_AO {
- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_CLK81>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8b-uart", "amlogic,meson-ao-uart";
+ clocks = <&xtal>, <&clkc CLKID_CLK81>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_A {
- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART0>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8b-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_B {
- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART1>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8b-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&uart_C {
- compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
- clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART2>;
- clock-names = "baud", "xtal", "pclk";
+ compatible = "amlogic,meson8b-uart";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "pclk", "baud";
};
&usb0 {
diff --git a/arch/arm/boot/dts/omap3-beagle-ab4.dts b/arch/arm/boot/dts/omap3-beagle-ab4.dts
new file mode 100644
index 000000000000..990ff2d84686
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-beagle-ab4.dts
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/dts-v1/;
+
+#include "omap3-beagle.dts"
+
+/ {
+ model = "TI OMAP3 BeagleBoard A to B4";
+ compatible = "ti,omap3-beagle-ab4", "ti,omap3-beagle", "ti,omap3430", "ti,omap3";
+};
+
+/*
+ * Workaround for capacitor C70 issue, see "Boards revision A and < B5"
+ * section at https://elinux.org/BeagleBoard_Community
+ */
+
+/* Unusable as clocksource because of unreliable oscillator */
+&counter32k {
+ status = "disabled";
+};
+
+/* Unusable as clockevent because of unreliable oscillator, allow to idle */
+&timer1_target {
+ /delete-property/ti,no-reset-on-init;
+ /delete-property/ti,no-idle;
+ timer@0 {
+ /delete-property/ti,timer-alwon;
+ };
+};
+
+/* Preferred always-on timer for clocksource */
+&timer12_target {
+ ti,no-reset-on-init;
+ ti,no-idle;
+ timer@0 {
+ /* Always clocked by secure_32k_fck */
+ };
+};
+
+/* Preferred timer for clockevent */
+&timer2_target {
+ ti,no-reset-on-init;
+ ti,no-idle;
+ timer@0 {
+ assigned-clocks = <&gpt2_fck>;
+ assigned-clock-parents = <&sys_ck>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index f9f34b8458e9..0548b391334f 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -304,39 +304,6 @@
phys = <0 &hsusb2_phy>;
};
-/* Unusable as clocksource because of unreliable oscillator */
-&counter32k {
- status = "disabled";
-};
-
-/* Unusable as clockevent because if unreliable oscillator, allow to idle */
-&timer1_target {
- /delete-property/ti,no-reset-on-init;
- /delete-property/ti,no-idle;
- timer@0 {
- /delete-property/ti,timer-alwon;
- };
-};
-
-/* Preferred always-on timer for clocksource */
-&timer12_target {
- ti,no-reset-on-init;
- ti,no-idle;
- timer@0 {
- /* Always clocked by secure_32k_fck */
- };
-};
-
-/* Preferred timer for clockevent */
-&timer2_target {
- ti,no-reset-on-init;
- ti,no-idle;
- timer@0 {
- assigned-clocks = <&gpt2_fck>;
- assigned-clock-parents = <&sys_ck>;
- };
-};
-
&twl_gpio {
ti,use-leds;
/* pullups: BIT(1) */
diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
index 5e55198e4576..54cd37336be7 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
@@ -158,6 +158,24 @@
status = "disabled";
};
+/* Unusable as clockevent because if unreliable oscillator, allow to idle */
+&timer1_target {
+ /delete-property/ti,no-reset-on-init;
+ /delete-property/ti,no-idle;
+ timer@0 {
+ /delete-property/ti,timer-alwon;
+ };
+};
+
+/* Preferred timer for clockevent */
+&timer12_target {
+ ti,no-reset-on-init;
+ ti,no-idle;
+ timer@0 {
+ /* Always clocked by secure_32k_fck */
+ };
+};
+
&twl_gpio {
ti,use-leds;
/*
diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts
index c2995a280729..162d0726b008 100644
--- a/arch/arm/boot/dts/omap3-devkit8000.dts
+++ b/arch/arm/boot/dts/omap3-devkit8000.dts
@@ -14,36 +14,3 @@
display2 = &tv0;
};
};
-
-/* Unusable as clocksource because of unreliable oscillator */
-&counter32k {
- status = "disabled";
-};
-
-/* Unusable as clockevent because if unreliable oscillator, allow to idle */
-&timer1_target {
- /delete-property/ti,no-reset-on-init;
- /delete-property/ti,no-idle;
- timer@0 {
- /delete-property/ti,timer-alwon;
- };
-};
-
-/* Preferred always-on timer for clocksource */
-&timer12_target {
- ti,no-reset-on-init;
- ti,no-idle;
- timer@0 {
- /* Always clocked by secure_32k_fck */
- };
-};
-
-/* Preferred timer for clockevent */
-&timer2_target {
- ti,no-reset-on-init;
- ti,no-idle;
- timer@0 {
- assigned-clocks = <&gpt2_fck>;
- assigned-clock-parents = <&sys_ck>;
- };
-};
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 8eed9e3a92e9..5868eb512f69 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -718,8 +718,8 @@
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
assigned-clocks = <&cru SCLK_HDMI_PHY>;
assigned-clock-parents = <&hdmi_phy>;
- clocks = <&cru SCLK_HDMI_HDCP>, <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_CEC>;
- clock-names = "isfr", "iahb", "cec";
+ clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;
+ clock-names = "iahb", "isfr", "cec";
pinctrl-names = "default";
pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>;
resets = <&cru SRST_HDMI_P>;
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 85d56c63e49a..26b9bbe310af 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -971,7 +971,7 @@
status = "disabled";
};
- crypto: cypto-controller@ff8a0000 {
+ crypto: crypto@ff8a0000 {
compatible = "rockchip,rk3288-crypto";
reg = <0x0 0xff8a0000 0x0 0x4000>;
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts
index 367ba48aac3e..b587e4ec11e5 100644
--- a/arch/arm/boot/dts/spear320-hmi.dts
+++ b/arch/arm/boot/dts/spear320-hmi.dts
@@ -235,7 +235,6 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x41>;
- irq-over-gpio;
irq-gpios = <&gpiopinctrl 29 0x4>;
id = <0>;
blocks = <0x5>;
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
index ce104f9552d3..dcb03ce7cbd4 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
@@ -203,10 +203,6 @@
cap-sd-highspeed;
cap-mmc-highspeed;
/* All direction control is used */
- st,sig-dir-cmd;
- st,sig-dir-dat0;
- st,sig-dir-dat2;
- st,sig-dir-dat31;
st,sig-pin-fbclk;
full-pwr-cycle;
vmmc-supply = <&ab8500_ldo_aux3_reg>;
diff --git a/arch/arm/boot/dts/tegra124-nyan-big-fhd.dts b/arch/arm/boot/dts/tegra124-nyan-big-fhd.dts
index d35fb79d2f51..4db43324dafa 100644
--- a/arch/arm/boot/dts/tegra124-nyan-big-fhd.dts
+++ b/arch/arm/boot/dts/tegra124-nyan-big-fhd.dts
@@ -5,7 +5,13 @@
/ {
/* Version of Nyan Big with 1080p panel */
- panel {
- compatible = "auo,b133htn01";
+ host1x@50000000 {
+ dpaux@545c0000 {
+ aux-bus {
+ panel: panel {
+ compatible = "auo,b133htn01";
+ };
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/tegra124-nyan-big.dts b/arch/arm/boot/dts/tegra124-nyan-big.dts
index 1d2aac2cb6d0..fdc1d64dfff9 100644
--- a/arch/arm/boot/dts/tegra124-nyan-big.dts
+++ b/arch/arm/boot/dts/tegra124-nyan-big.dts
@@ -13,12 +13,15 @@
"google,nyan-big-rev1", "google,nyan-big-rev0",
"google,nyan-big", "google,nyan", "nvidia,tegra124";
- panel: panel {
- compatible = "auo,b133xtn01";
-
- power-supply = <&vdd_3v3_panel>;
- backlight = <&backlight>;
- ddc-i2c-bus = <&dpaux>;
+ host1x@50000000 {
+ dpaux@545c0000 {
+ aux-bus {
+ panel: panel {
+ compatible = "auo,b133xtn01";
+ backlight = <&backlight>;
+ };
+ };
+ };
};
mmc@700b0400 { /* SD Card on this bus */
diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze.dts b/arch/arm/boot/dts/tegra124-nyan-blaze.dts
index 677babde6460..abdf4456826f 100644
--- a/arch/arm/boot/dts/tegra124-nyan-blaze.dts
+++ b/arch/arm/boot/dts/tegra124-nyan-blaze.dts
@@ -15,12 +15,15 @@
"google,nyan-blaze-rev0", "google,nyan-blaze",
"google,nyan", "nvidia,tegra124";
- panel: panel {
- compatible = "samsung,ltn140at29-301";
-
- power-supply = <&vdd_3v3_panel>;
- backlight = <&backlight>;
- ddc-i2c-bus = <&dpaux>;
+ host1x@50000000 {
+ dpaux@545c0000 {
+ aux-bus {
+ panel: panel {
+ compatible = "samsung,ltn140at29-301";
+ backlight = <&backlight>;
+ };
+ };
+ };
};
sound {
diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts
index 232c90604df9..6a9592ceb5f2 100644
--- a/arch/arm/boot/dts/tegra124-venice2.dts
+++ b/arch/arm/boot/dts/tegra124-venice2.dts
@@ -48,6 +48,13 @@
dpaux@545c0000 {
vdd-supply = <&vdd_3v3_panel>;
status = "okay";
+
+ aux-bus {
+ panel: panel {
+ compatible = "lg,lp129qe";
+ backlight = <&backlight>;
+ };
+ };
};
};
@@ -1080,13 +1087,6 @@
};
};
- panel: panel {
- compatible = "lg,lp129qe";
- power-supply = <&vdd_3v3_panel>;
- backlight = <&backlight>;
- ddc-i2c-bus = <&dpaux>;
- };
-
vdd_mux: regulator-mux {
compatible = "regulator-fixed";
regulator-name = "+VDD_MUX";
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index e849367c0566..b58d45a03607 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -258,7 +258,6 @@ CONFIG_MINIX_FS=m
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index cae09010a799..aa061074db78 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -158,6 +158,7 @@ CONFIG_CHARGER_MAX14577=y
CONFIG_CHARGER_MAX77693=y
CONFIG_CHARGER_MAX8997=y
CONFIG_CHARGER_MAX8998=y
+CONFIG_CHARGER_SMB347=y
CONFIG_CHARGER_TPS65090=y
CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_NTC_THERMISTOR=y
diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig
index ec84d80096b1..0788a892e160 100644
--- a/arch/arm/configs/ezx_defconfig
+++ b/arch/arm/configs/ezx_defconfig
@@ -309,7 +309,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_SMB_FS=m
CONFIG_CIFS=m
diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig
index 6db871d4e077..015b7ef237de 100644
--- a/arch/arm/configs/imote2_defconfig
+++ b/arch/arm/configs/imote2_defconfig
@@ -283,7 +283,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_SMB_FS=m
CONFIG_CIFS=m
diff --git a/arch/arm/configs/imxrt_defconfig b/arch/arm/configs/imxrt_defconfig
new file mode 100644
index 000000000000..52dba3762996
--- /dev/null
+++ b/arch/arm/configs/imxrt_defconfig
@@ -0,0 +1,35 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_BPF_SYSCALL=y
+CONFIG_SCHED_AUTOGROUP=y
+# CONFIG_MMU is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMXRT=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x80000000
+CONFIG_DRAM_SIZE=0x02000000
+CONFIG_BINFMT_FLAT=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_IMX_WEIM=y
+CONFIG_LEGACY_PTY_COUNT=2
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_PINCTRL_IMXRT1050=y
+CONFIG_GPIO_MXC=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+CONFIG_CLK_IMXRT1050=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_EXFAT_FS=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_UTF8=y
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index 4dfe321a79f6..5b485722ccf9 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -79,7 +79,6 @@ CONFIG_CRAMFS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index 18a21faa834c..de2cc6759cae 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -94,7 +94,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 33c917df7b32..b1bcb858216b 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -213,7 +213,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
index b6ddb9884326..2dfa33d7dca3 100644
--- a/arch/arm/configs/lart_defconfig
+++ b/arch/arm/configs/lart_defconfig
@@ -59,7 +59,6 @@ CONFIG_CRAMFS=m
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_850=m
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index fe8d760256a4..70241ad2b550 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -24,11 +24,6 @@ CONFIG_MACH_DM355_LEOPARD=y
CONFIG_MACH_MITYOMAPL138=y
CONFIG_MACH_OMAPL138_HAWKBOARD=y
CONFIG_ARCH_MXC=y
-CONFIG_MACH_MX21ADS=y
-CONFIG_MACH_MX27ADS=y
-CONFIG_MACH_MX27_3DS=y
-CONFIG_MACH_IMX27_VISSTRIM_M10=y
-CONFIG_MACH_PCA100=y
CONFIG_SOC_IMX25=y
CONFIG_SOC_IMX27=y
CONFIG_ARCH_MVEBU=y
@@ -57,11 +52,9 @@ CONFIG_MACH_WNR854T=y
CONFIG_MACH_RD88F5181L_GE=y
CONFIG_MACH_RD88F5181L_FXO=y
CONFIG_MACH_RD88F6183AP_GE=y
-CONFIG_ARCH_U300=y
+CONFIG_ARCH_SUNXI=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_CPU_FREQ=y
@@ -85,6 +78,8 @@ CONFIG_NET_PKTGEN=m
CONFIG_CFG80211=y
CONFIG_MAC80211=y
CONFIG_PCI_MVEBU=y
+CONFIG_ARCH_VERSATILE=y
+CONFIG_PCI_VERSATILE=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_IMX_WEIM=y
@@ -111,6 +106,9 @@ CONFIG_EEPROM_AT24=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=m
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_BLK=y
CONFIG_CHR_DEV_SG=m
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
@@ -143,7 +141,10 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=6
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_ASPEED_VUART=m
+CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_ATMEL=y
CONFIG_SERIAL_ATMEL_CONSOLE=y
CONFIG_SERIAL_ATMEL_TTYAT=y
@@ -159,11 +160,11 @@ CONFIG_I2C_ASPEED=m
CONFIG_I2C_AT91=y
CONFIG_I2C_IMX=y
CONFIG_I2C_MV64XXX=y
-CONFIG_I2C_NOMADIK=y
CONFIG_SPI=y
CONFIG_SPI_ATMEL=y
CONFIG_SPI_IMX=y
CONFIG_SPI_ORION=y
+CONFIG_SPI_SUN6I=y
CONFIG_GPIO_ASPEED=m
CONFIG_GPIO_ASPEED_SGPIO=y
CONFIG_GPIO_MXC=y
@@ -180,14 +181,15 @@ CONFIG_THERMAL=y
CONFIG_KIRKWOOD_THERMAL=y
CONFIG_AT91SAM9X_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
+CONFIG_SUNXI_WATCHDOG=y
CONFIG_NPCM7XX_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_MFD_ATMEL_HLCDC=y
-# CONFIG_ABX500_CORE is not set
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_ASPEED=m
CONFIG_VIDEO_ATMEL_ISI=m
@@ -196,6 +198,7 @@ CONFIG_DRM_ATMEL_HLCDC=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_EDP=y
CONFIG_DRM_ASPEED_GFX=m
+CONFIG_FB=y
CONFIG_FB_IMX=y
CONFIG_FB_ATMEL=y
CONFIG_BACKLIGHT_ATMEL_LCDC=y
@@ -249,6 +252,7 @@ CONFIG_MMC_SDHCI_PLTFM=m
CONFIG_MMC_SDHCI_OF_ASPEED=m
CONFIG_MMC_ATMELMCI=y
CONFIG_MMC_MVSDIO=y
+CONFIG_MMC_SUNXI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
@@ -303,8 +307,8 @@ CONFIG_CRYPTO_DEV_MARVELL_CESA=y
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_PREEMPT is not set
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 8863fa969ede..6e0c8c19b35c 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -24,7 +24,9 @@ CONFIG_ARCH_BCM_NSP=y
CONFIG_ARCH_BCM_5301X=y
CONFIG_ARCH_BCM_281XX=y
CONFIG_ARCH_BCM_21664=y
+CONFIG_ARCH_BCM_23550=y
CONFIG_ARCH_BCM2835=y
+CONFIG_ARCH_BCM_53573=y
CONFIG_ARCH_BCM_63XX=y
CONFIG_ARCH_BRCMSTB=y
CONFIG_ARCH_BERLIN=y
@@ -32,6 +34,7 @@ CONFIG_MACH_BERLIN_BG2=y
CONFIG_MACH_BERLIN_BG2CD=y
CONFIG_MACH_BERLIN_BG2Q=y
CONFIG_ARCH_DIGICOLOR=y
+CONFIG_ARCH_AIROHA=y
CONFIG_ARCH_EXYNOS=y
CONFIG_ARCH_HIGHBANK=y
CONFIG_ARCH_HISI=y
@@ -75,6 +78,7 @@ CONFIG_SOC_AM43XX=y
CONFIG_SOC_DRA7XX=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MSM8916=y
CONFIG_ARCH_MSM8960=y
CONFIG_ARCH_MSM8974=y
CONFIG_ARCH_ROCKCHIP=y
@@ -109,11 +113,13 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPUFREQ_DT=y
CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
CONFIG_ARM_RASPBERRYPI_CPUFREQ=y
CONFIG_ARM_SCMI_CPUFREQ=y
CONFIG_QORIQ_CPUFREQ=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
CONFIG_ARM_ZYNQ_CPUIDLE=y
CONFIG_ARM_EXYNOS_CPUIDLE=y
CONFIG_ARM_TEGRA_CPUIDLE=y
@@ -157,6 +163,8 @@ CONFIG_IPV6_MIP6=m
CONFIG_IPV6_TUNNEL=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_NET_DSA=m
+CONFIG_QRTR=m
+CONFIG_QRTR_SMD=m
CONFIG_CAN=y
CONFIG_CAN_AT91=m
CONFIG_CAN_FLEXCAN=m
@@ -169,6 +177,7 @@ CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
+CONFIG_BT_QCOMSMD=m
CONFIG_CFG80211=m
CONFIG_MAC80211=m
CONFIG_RFKILL=y
@@ -225,6 +234,7 @@ CONFIG_AD525X_DPOT_I2C=y
CONFIG_ICS932S401=y
CONFIG_ATMEL_SSC=m
CONFIG_QCOM_COINCELL=m
+CONFIG_QCOM_FASTRPC=m
CONFIG_APDS9802ALS=y
CONFIG_ISL29003=y
CONFIG_PCI_ENDPOINT_TEST=m
@@ -282,12 +292,14 @@ CONFIG_MARVELL_PHY=y
CONFIG_AT803X_PHY=y
CONFIG_ROCKCHIP_PHY=y
CONFIG_DP83867_PHY=y
+CONFIG_USB_BRCMSTB=m
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8152=m
CONFIG_USB_LAN78XX=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
+CONFIG_WCN36XX=m
CONFIG_BRCMFMAC=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
@@ -316,6 +328,7 @@ CONFIG_TOUCHSCREEN_ST1232=m
CONFIG_TOUCHSCREEN_STMPE=y
CONFIG_TOUCHSCREEN_SUN4I=y
CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PM8941_PWRKEY=y
CONFIG_INPUT_MAX77693_HAPTIC=m
CONFIG_INPUT_MAX8997_HAPTIC=m
CONFIG_INPUT_CPCAP_PWRBUTTON=m
@@ -398,6 +411,8 @@ CONFIG_I2C_IMX=y
CONFIG_I2C_MESON=y
CONFIG_I2C_MV64XXX=y
CONFIG_I2C_OWL=y
+CONFIG_I2C_QCOM_CCI=m
+CONFIG_I2C_QUP=y
CONFIG_I2C_RIIC=y
CONFIG_I2C_RK3X=y
CONFIG_I2C_S3C2410=y
@@ -426,6 +441,7 @@ CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
CONFIG_SPI_ROCKCHIP=m
CONFIG_SPI_RSPI=y
+CONFIG_SPI_QUP=m
CONFIG_SPI_S3C64XX=m
CONFIG_SPI_SH_MSIOF=m
CONFIG_SPI_SH_HSPI=y
@@ -476,6 +492,8 @@ CONFIG_GPIO_TWL4030=y
CONFIG_POWER_RESET_AS3722=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_MSM=y
+CONFIG_POWER_RESET_QCOM_PON=y
CONFIG_POWER_RESET_ST=y
CONFIG_POWER_RESET_KEYSTONE=y
CONFIG_POWER_RESET_RMOBILE=y
@@ -493,6 +511,7 @@ CONFIG_CHARGER_MAX14577=m
CONFIG_CHARGER_MAX77693=m
CONFIG_CHARGER_MAX8997=m
CONFIG_CHARGER_MAX8998=m
+CONFIG_CHARGER_SMB347=m
CONFIG_CHARGER_TPS65090=y
CONFIG_SENSORS_ARM_SCMI=y
CONFIG_SENSORS_ASPEED=m
@@ -516,6 +535,7 @@ CONFIG_ST_THERMAL_MEMMAP=y
CONFIG_TEGRA_SOCTHERM=m
CONFIG_TEGRA30_TSENSOR=m
CONFIG_GENERIC_ADC_THERMAL=m
+CONFIG_QCOM_TSENS=y
CONFIG_UNIPHIER_THERMAL=y
CONFIG_DA9063_WATCHDOG=m
CONFIG_XILINX_WATCHDOG=y
@@ -531,11 +551,13 @@ CONFIG_SUNXI_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_ST_LPC_WATCHDOG=y
CONFIG_TEGRA_WATCHDOG=m
+CONFIG_QCOM_WDT=m
CONFIG_MESON_WATCHDOG=y
CONFIG_DIGICOLOR_WATCHDOG=y
CONFIG_RENESAS_WDT=m
CONFIG_RENESAS_RZAWDT=m
CONFIG_STPMIC1_WATCHDOG=y
+CONFIG_PM8916_WATCHDOG=m
CONFIG_BCM47XX_WDT=y
CONFIG_BCM2835_WDT=y
CONFIG_BCM_KONA_WDT=y
@@ -602,7 +624,8 @@ CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_PBIAS=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_QCOM_RPM=y
-CONFIG_REGULATOR_QCOM_SMD_RPM=m
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
+CONFIG_REGULATOR_QCOM_SPMI=y
CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_RN5T618=y
CONFIG_REGULATOR_S2MPA01=m
@@ -691,6 +714,7 @@ CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
CONFIG_DRM_LVDS_CODEC=m
+CONFIG_DRM_DISPLAY_CONNECTOR=m
CONFIG_DRM_NXP_PTN3460=m
CONFIG_DRM_PARADE_PS8622=m
CONFIG_DRM_SII902X=m
@@ -741,6 +765,8 @@ CONFIG_SND_SOC_FSL_SAI=m
CONFIG_SND_PXA_SOC_SSP=m
CONFIG_SND_MMP_SOC_SSPA=m
CONFIG_SND_PXA910_SOC=m
+CONFIG_SND_SOC_QCOM=m
+CONFIG_SND_SOC_APQ8016_SBC=m
CONFIG_SND_SOC_ROCKCHIP=m
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
CONFIG_SND_SOC_ROCKCHIP_MAX98090=m
@@ -774,6 +800,8 @@ CONFIG_SND_SOC_TEGRA_MAX98090=m
CONFIG_SND_SOC_AK4642=m
CONFIG_SND_SOC_CPCAP=m
CONFIG_SND_SOC_CS42L51_I2C=m
+CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
+CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
CONFIG_SND_SOC_SGTL5000=m
CONFIG_SND_SOC_STI_SAS=m
CONFIG_SND_SOC_WM8978=m
@@ -936,6 +964,7 @@ CONFIG_RTC_DRV_AT91SAM9=m
CONFIG_RTC_DRV_VT8500=y
CONFIG_RTC_DRV_SUNXI=y
CONFIG_RTC_DRV_MV=y
+CONFIG_RTC_DRV_PM8XXX=m
CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_DRV_ST_LPC=y
CONFIG_RTC_DRV_STM32=y
@@ -984,26 +1013,47 @@ CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_S2MPS11=m
CONFIG_CLK_RASPBERRYPI=y
CONFIG_COMMON_CLK_QCOM=y
+CONFIG_QCOM_A53PLL=y
+CONFIG_QCOM_CLK_APCS_MSM8916=y
CONFIG_QCOM_CLK_RPM=y
+CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_APQ_MMCC_8084=y
CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_GCC_8916=y
CONFIG_MSM_MMCC_8960=y
CONFIG_MSM_MMCC_8974=y
+CONFIG_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_QCOM=y
CONFIG_MICROCHIP_PIT64B=y
CONFIG_BCM2835_MBOX=y
+CONFIG_QCOM_APCS_IPC=y
+CONFIG_QCOM_IPCC=y
CONFIG_ROCKCHIP_IOMMU=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_EXYNOS_IOMMU=y
+CONFIG_QCOM_IOMMU=y
CONFIG_REMOTEPROC=y
+CONFIG_QCOM_Q6V5_MSS=m
+CONFIG_QCOM_SYSMON=m
+CONFIG_QCOM_WCNSS_PIL=m
CONFIG_ST_REMOTEPROC=m
+CONFIG_RPMSG_QCOM_SMD=y
CONFIG_RPMSG_VIRTIO=m
CONFIG_ASPEED_LPC_CTRL=m
CONFIG_ASPEED_LPC_SNOOP=m
CONFIG_ASPEED_P2A_CTRL=m
CONFIG_RASPBERRYPI_POWER=y
+CONFIG_QCOM_CPR=y
CONFIG_QCOM_GSBI=y
-CONFIG_QCOM_SMD_RPM=m
+CONFIG_QCOM_RMTFS_MEM=m
+CONFIG_QCOM_RPMPD=y
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMP2P=y
+CONFIG_QCOM_SMSM=y
+CONFIG_QCOM_SOCINFO=m
+CONFIG_QCOM_STATS=m
CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_ARCH_EMEV2=y
CONFIG_ARCH_R8A7794=y
@@ -1036,6 +1086,7 @@ CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=m
CONFIG_EXTCON_MAX14577=m
CONFIG_EXTCON_MAX77693=m
CONFIG_EXTCON_MAX8997=m
+CONFIG_EXTCON_USB_GPIO=y
CONFIG_TI_AEMIF=y
CONFIG_STM32_FMC2_EBI=y
CONFIG_EXYNOS5422_DMC=m
@@ -1048,6 +1099,7 @@ CONFIG_BERLIN2_ADC=m
CONFIG_CPCAP_ADC=m
CONFIG_EXYNOS_ADC=m
CONFIG_MESON_SARADC=m
+CONFIG_QCOM_SPMI_VADC=m
CONFIG_ROCKCHIP_SARADC=m
CONFIG_STM32_ADC_CORE=m
CONFIG_STM32_ADC=m
@@ -1090,9 +1142,11 @@ CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_HIX5HD2_SATA=y
CONFIG_PHY_BERLIN_SATA=y
CONFIG_PHY_BERLIN_USB=y
+CONFIG_PHY_BRCM_USB=m
CONFIG_PHY_MMP3_USB=m
CONFIG_PHY_CPCAP_USB=m
CONFIG_PHY_QCOM_APQ8064_SATA=m
+CONFIG_PHY_QCOM_USB_HS=y
CONFIG_PHY_RCAR_GEN2=m
CONFIG_PHY_ROCKCHIP_DP=m
CONFIG_PHY_ROCKCHIP_USB=y
@@ -1110,6 +1164,7 @@ CONFIG_TI_PIPE3=y
CONFIG_TWL4030_USB=m
CONFIG_RAS=y
CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_QCOM_QFPROM=y
CONFIG_ROCKCHIP_EFUSE=m
CONFIG_NVMEM_SUNXI_SID=y
CONFIG_NVMEM_VF610_OCOTP=y
@@ -1122,6 +1177,8 @@ CONFIG_FSI_MASTER_ASPEED=m
CONFIG_FSI_SCOM=m
CONFIG_FSI_SBEFIFO=m
CONFIG_FSI_OCC=m
+CONFIG_INTERCONNECT_QCOM=y
+CONFIG_INTERCONNECT_QCOM_MSM8916=y
CONFIG_COUNTER=m
CONFIG_STM32_TIMER_CNT=m
CONFIG_STM32_LPTIMER_CNT=m
@@ -1161,6 +1218,8 @@ CONFIG_CRYPTO_DEV_ATMEL_AES=m
CONFIG_CRYPTO_DEV_ATMEL_TDES=m
CONFIG_CRYPTO_DEV_ATMEL_SHA=m
CONFIG_CRYPTO_DEV_MARVELL_CESA=m
+CONFIG_CRYPTO_DEV_QCE=m
+CONFIG_CRYPTO_DEV_QCOM_RNG=m
CONFIG_CRYPTO_DEV_ROCKCHIP=m
CONFIG_CRYPTO_DEV_STM32_CRC=m
CONFIG_CRYPTO_DEV_STM32_HASH=m
diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
index 2e3b20ef0db1..c3c171cec91b 100644
--- a/arch/arm/configs/netwinder_defconfig
+++ b/arch/arm/configs/netwinder_defconfig
@@ -71,7 +71,6 @@ CONFIG_NFS_V3=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_SMB_FS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_NLS_CODEPAGE_437=y
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig
index dedaaae3d0d8..29b1f192afbb 100644
--- a/arch/arm/configs/pxa_defconfig
+++ b/arch/arm/configs/pxa_defconfig
@@ -41,8 +41,6 @@ CONFIG_MACH_EXEDA=y
CONFIG_MACH_CM_X300=y
CONFIG_MACH_CAPC7117=y
CONFIG_ARCH_GUMSTIX=y
-CONFIG_MACH_INTELMOTE2=y
-CONFIG_MACH_STARGATE2=y
CONFIG_MACH_XCEP=y
CONFIG_TRIZEPS_PXA=y
CONFIG_MACH_TRIZEPS4WL=y
@@ -487,7 +485,6 @@ CONFIG_SND_SOC_ZYLONITE=m
CONFIG_SND_PXA2XX_SOC_HX4700=m
CONFIG_SND_PXA2XX_SOC_MAGICIAN=m
CONFIG_SND_PXA2XX_SOC_MIOA701=m
-CONFIG_SND_PXA2XX_SOC_IMOTE2=m
CONFIG_SND_SOC_AK4642=m
CONFIG_SND_SOC_WM8978=m
CONFIG_SND_SIMPLE_CARD=m
diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 0368068e04d9..07b0494ef743 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -26,6 +26,13 @@ CONFIG_FORCE_MAX_ZONEORDER=15
CONFIG_UACCESS_WITH_MEMCPY=y
# CONFIG_ATAGS is not set
CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPU_IDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
CONFIG_KERNEL_MODE_NEON=y
@@ -82,7 +89,11 @@ CONFIG_DEVTMPFS_MOUNT=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set
CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=1
@@ -170,21 +181,21 @@ CONFIG_RTC_DRV_AT91RM9200=y
CONFIG_RTC_DRV_AT91SAM9=y
CONFIG_DMADEVICES=y
CONFIG_AT_XDMAC=y
-CONFIG_DMATEST=y
CONFIG_STAGING=y
CONFIG_MICROCHIP_PIT64B=y
# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_ATMEL_EBI is not set
CONFIG_IIO=y
CONFIG_IIO_SW_TRIGGER=y
CONFIG_AT91_SAMA5D2_ADC=y
CONFIG_PWM=y
CONFIG_PWM_ATMEL=y
+CONFIG_MCHP_EIC=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_FANOTIFY=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
@@ -192,9 +203,19 @@ CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=y
CONFIG_LSM="N"
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-# CONFIG_CRYPTO_HW is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CFB=y
+CONFIG_CRYPTO_OFB=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_CRYPTO_DEV_ATMEL_AES=y
+CONFIG_CRYPTO_DEV_ATMEL_TDES=y
+CONFIG_CRYPTO_DEV_ATMEL_SHA=y
CONFIG_CRC_CCITT=y
CONFIG_CRC_ITU_T=y
CONFIG_DMA_CMA=y
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 2c2702ec6d02..db8df8a3a7b1 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -69,9 +69,13 @@ CONFIG_INPUT_DA9063_ONKEY=y
CONFIG_INPUT_ADXL34X=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_8250_EM=y
+# CONFIG_SERIAL_8250_PERICOM is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DEMUX_PINCTRL=y
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index d06aa64e05a1..c2d79a67f81f 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -86,7 +86,6 @@ CONFIG_ROMFS_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_ISO8859_1=m
CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig
index 989599ce5300..c28539bfd128 100644
--- a/arch/arm/configs/viper_defconfig
+++ b/arch/arm/configs/viper_defconfig
@@ -145,7 +145,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_850=m
diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig
index d3b98c4d225b..25bb6995f105 100644
--- a/arch/arm/configs/zeus_defconfig
+++ b/arch/arm/configs/zeus_defconfig
@@ -160,7 +160,6 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_850=m
diff --git a/arch/arm/crypto/aes-neonbs-core.S b/arch/arm/crypto/aes-neonbs-core.S
index 7d0cc7f226a5..7b61032f29fa 100644
--- a/arch/arm/crypto/aes-neonbs-core.S
+++ b/arch/arm/crypto/aes-neonbs-core.S
@@ -758,29 +758,24 @@ ENTRY(aesbs_cbc_decrypt)
ENDPROC(aesbs_cbc_decrypt)
.macro next_ctr, q
- vmov.32 \q\()h[1], r10
+ vmov \q\()h, r9, r10
adds r10, r10, #1
- vmov.32 \q\()h[0], r9
adcs r9, r9, #0
- vmov.32 \q\()l[1], r8
+ vmov \q\()l, r7, r8
adcs r8, r8, #0
- vmov.32 \q\()l[0], r7
adc r7, r7, #0
vrev32.8 \q, \q
.endm
/*
* aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
- * int rounds, int blocks, u8 ctr[], u8 final[])
+ * int rounds, int bytes, u8 ctr[])
*/
ENTRY(aesbs_ctr_encrypt)
mov ip, sp
push {r4-r10, lr}
- ldm ip, {r5-r7} // load args 4-6
- teq r7, #0
- addne r5, r5, #1 // one extra block if final != 0
-
+ ldm ip, {r5, r6} // load args 4-5
vld1.8 {q0}, [r6] // load counter
vrev32.8 q1, q0
vmov r9, r10, d3
@@ -792,20 +787,19 @@ ENTRY(aesbs_ctr_encrypt)
adc r7, r7, #0
99: vmov q1, q0
+ sub lr, r5, #1
vmov q2, q0
+ adr ip, 0f
vmov q3, q0
+ and lr, lr, #112
vmov q4, q0
+ cmp r5, #112
vmov q5, q0
+ sub ip, ip, lr, lsl #1
vmov q6, q0
+ add ip, ip, lr, lsr #2
vmov q7, q0
-
- adr ip, 0f
- sub lr, r5, #1
- and lr, lr, #7
- cmp r5, #8
- sub ip, ip, lr, lsl #5
- sub ip, ip, lr, lsl #2
- movlt pc, ip // computed goto if blocks < 8
+ movle pc, ip // computed goto if bytes < 112
next_ctr q1
next_ctr q2
@@ -820,12 +814,14 @@ ENTRY(aesbs_ctr_encrypt)
bl aesbs_encrypt8
adr ip, 1f
- and lr, r5, #7
- cmp r5, #8
- movgt r4, #0
- ldrle r4, [sp, #40] // load final in the last round
- sub ip, ip, lr, lsl #2
- movlt pc, ip // computed goto if blocks < 8
+ sub lr, r5, #1
+ cmp r5, #128
+ bic lr, lr, #15
+ ands r4, r5, #15 // preserves C flag
+ teqcs r5, r5 // set Z flag if not last iteration
+ sub ip, ip, lr, lsr #2
+ rsb r4, r4, #16
+ movcc pc, ip // computed goto if bytes < 128
vld1.8 {q8}, [r1]!
vld1.8 {q9}, [r1]!
@@ -834,46 +830,70 @@ ENTRY(aesbs_ctr_encrypt)
vld1.8 {q12}, [r1]!
vld1.8 {q13}, [r1]!
vld1.8 {q14}, [r1]!
- teq r4, #0 // skip last block if 'final'
-1: bne 2f
+1: subne r1, r1, r4
vld1.8 {q15}, [r1]!
-2: adr ip, 3f
- cmp r5, #8
- sub ip, ip, lr, lsl #3
- movlt pc, ip // computed goto if blocks < 8
+ add ip, ip, #2f - 1b
veor q0, q0, q8
- vst1.8 {q0}, [r0]!
veor q1, q1, q9
- vst1.8 {q1}, [r0]!
veor q4, q4, q10
- vst1.8 {q4}, [r0]!
veor q6, q6, q11
- vst1.8 {q6}, [r0]!
veor q3, q3, q12
- vst1.8 {q3}, [r0]!
veor q7, q7, q13
- vst1.8 {q7}, [r0]!
veor q2, q2, q14
+ bne 3f
+ veor q5, q5, q15
+
+ movcc pc, ip // computed goto if bytes < 128
+
+ vst1.8 {q0}, [r0]!
+ vst1.8 {q1}, [r0]!
+ vst1.8 {q4}, [r0]!
+ vst1.8 {q6}, [r0]!
+ vst1.8 {q3}, [r0]!
+ vst1.8 {q7}, [r0]!
vst1.8 {q2}, [r0]!
- teq r4, #0 // skip last block if 'final'
- W(bne) 5f
-3: veor q5, q5, q15
+2: subne r0, r0, r4
vst1.8 {q5}, [r0]!
-4: next_ctr q0
+ next_ctr q0
- subs r5, r5, #8
+ subs r5, r5, #128
bgt 99b
vst1.8 {q0}, [r6]
pop {r4-r10, pc}
-5: vst1.8 {q5}, [r4]
- b 4b
+3: adr lr, .Lpermute_table + 16
+ cmp r5, #16 // Z flag remains cleared
+ sub lr, lr, r4
+ vld1.8 {q8-q9}, [lr]
+ vtbl.8 d16, {q5}, d16
+ vtbl.8 d17, {q5}, d17
+ veor q5, q8, q15
+ bcc 4f // have to reload prev if R5 < 16
+ vtbx.8 d10, {q2}, d18
+ vtbx.8 d11, {q2}, d19
+ mov pc, ip // branch back to VST sequence
+
+4: sub r0, r0, r4
+ vshr.s8 q9, q9, #7 // create mask for VBIF
+ vld1.8 {q8}, [r0] // reload
+ vbif q5, q8, q9
+ vst1.8 {q5}, [r0]
+ pop {r4-r10, pc}
ENDPROC(aesbs_ctr_encrypt)
+ .align 6
+.Lpermute_table:
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+ .byte 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+
.macro next_tweak, out, in, const, tmp
vshr.s64 \tmp, \in, #63
vand \tmp, \tmp, \const
@@ -888,6 +908,7 @@ ENDPROC(aesbs_ctr_encrypt)
* aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
* int blocks, u8 iv[], int reorder_last_tweak)
*/
+ .align 6
__xts_prepare8:
vld1.8 {q14}, [r7] // load iv
vmov.i32 d30, #0x87 // compose tweak mask vector
diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c
index 5c6cd3c63cbc..f00f042ef357 100644
--- a/arch/arm/crypto/aes-neonbs-glue.c
+++ b/arch/arm/crypto/aes-neonbs-glue.c
@@ -37,7 +37,7 @@ asmlinkage void aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 iv[]);
asmlinkage void aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
- int rounds, int blocks, u8 ctr[], u8 final[]);
+ int rounds, int blocks, u8 ctr[]);
asmlinkage void aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 iv[], int);
@@ -243,32 +243,25 @@ static int ctr_encrypt(struct skcipher_request *req)
err = skcipher_walk_virt(&walk, req, false);
while (walk.nbytes > 0) {
- unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
- u8 *final = (walk.total % AES_BLOCK_SIZE) ? buf : NULL;
+ const u8 *src = walk.src.virt.addr;
+ u8 *dst = walk.dst.virt.addr;
+ int bytes = walk.nbytes;
- if (walk.nbytes < walk.total) {
- blocks = round_down(blocks,
- walk.stride / AES_BLOCK_SIZE);
- final = NULL;
- }
+ if (unlikely(bytes < AES_BLOCK_SIZE))
+ src = dst = memcpy(buf + sizeof(buf) - bytes,
+ src, bytes);
+ else if (walk.nbytes < walk.total)
+ bytes &= ~(8 * AES_BLOCK_SIZE - 1);
kernel_neon_begin();
- aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
- ctx->rk, ctx->rounds, blocks, walk.iv, final);
+ aesbs_ctr_encrypt(dst, src, ctx->rk, ctx->rounds, bytes, walk.iv);
kernel_neon_end();
- if (final) {
- u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
- u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
+ if (unlikely(bytes < AES_BLOCK_SIZE))
+ memcpy(walk.dst.virt.addr,
+ buf + sizeof(buf) - bytes, bytes);
- crypto_xor_cpy(dst, src, final,
- walk.total % AES_BLOCK_SIZE);
-
- err = skcipher_walk_done(&walk, 0);
- break;
- }
- err = skcipher_walk_done(&walk,
- walk.nbytes - blocks * AES_BLOCK_SIZE);
+ err = skcipher_walk_done(&walk, walk.nbytes - bytes);
}
return err;
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 6fe67963ba5a..34fe8d2dd5d1 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -86,6 +86,10 @@
#define IMM12_MASK 0xfff
+/* the frame pointer used for stack unwinding */
+ARM( fpreg .req r11 )
+THUMB( fpreg .req r7 )
+
/*
* Enable and disable interrupts
*/
@@ -107,6 +111,16 @@
.endm
#endif
+#if __LINUX_ARM_ARCH__ < 7
+ .macro dsb, args
+ mcr p15, 0, r0, c7, c10, 4
+ .endm
+
+ .macro isb, args
+ mcr p15, 0, r0, c7, c5, 4
+ .endm
+#endif
+
.macro asm_trace_hardirqs_off, save=1
#if defined(CONFIG_TRACE_IRQFLAGS)
.if \save
@@ -199,43 +213,12 @@
.endm
.endr
- .macro get_current, rd
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
- mrc p15, 0, \rd, c13, c0, 3 @ get TPIDRURO register
-#else
- get_thread_info \rd
- ldr \rd, [\rd, #TI_TASK]
-#endif
- .endm
-
- .macro set_current, rn
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
- mcr p15, 0, \rn, c13, c0, 3 @ set TPIDRURO register
-#endif
- .endm
-
- .macro reload_current, t1:req, t2:req
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
- adr_l \t1, __entry_task @ get __entry_task base address
- mrc p15, 0, \t2, c13, c0, 4 @ get per-CPU offset
- ldr \t1, [\t1, \t2] @ load variable
- mcr p15, 0, \t1, c13, c0, 3 @ store in TPIDRURO
-#endif
- .endm
-
/*
* Get current thread_info.
*/
.macro get_thread_info, rd
-#ifdef CONFIG_THREAD_INFO_IN_TASK
/* thread_info is the first member of struct task_struct */
get_current \rd
-#else
- ARM( mov \rd, sp, lsr #THREAD_SIZE_ORDER + PAGE_SHIFT )
- THUMB( mov \rd, sp )
- THUMB( lsr \rd, \rd, #THREAD_SIZE_ORDER + PAGE_SHIFT )
- mov \rd, \rd, lsl #THREAD_SIZE_ORDER + PAGE_SHIFT
-#endif
.endm
/*
@@ -310,6 +293,80 @@
#define ALT_UP_B(label) b label
#endif
+ /*
+ * this_cpu_offset - load the per-CPU offset of this CPU into
+ * register 'rd'
+ */
+ .macro this_cpu_offset, rd:req
+#ifdef CONFIG_SMP
+ALT_SMP(mrc p15, 0, \rd, c13, c0, 4)
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L1_\@)
+.L0_\@:
+ .subsection 1
+.L1_\@: ldr_va \rd, __per_cpu_offset
+ b .L0_\@
+ .previous
+#endif
+#else
+ mov \rd, #0
+#endif
+ .endm
+
+ /*
+ * set_current - store the task pointer of this CPU's current task
+ */
+ .macro set_current, rn:req, tmp:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+9998: mcr p15, 0, \rn, c13, c0, 3 @ set TPIDRURO register
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L0_\@)
+ .subsection 1
+.L0_\@: str_va \rn, __current, \tmp
+ b .L1_\@
+ .previous
+.L1_\@:
+#endif
+#else
+ str_va \rn, __current, \tmp
+#endif
+ .endm
+
+ /*
+ * get_current - load the task pointer of this CPU's current task
+ */
+ .macro get_current, rd:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+9998: mrc p15, 0, \rd, c13, c0, 3 @ get TPIDRURO register
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L0_\@)
+ .subsection 1
+.L0_\@: ldr_va \rd, __current
+ b .L1_\@
+ .previous
+.L1_\@:
+#endif
+#else
+ ldr_va \rd, __current
+#endif
+ .endm
+
+ /*
+ * reload_current - reload the task pointer of this CPU's current task
+ * into the TLS register
+ */
+ .macro reload_current, t1:req, t2:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+#ifdef CONFIG_CPU_V6
+ALT_SMP(nop)
+ALT_UP_B(.L0_\@)
+#endif
+ ldr_this_cpu \t1, __entry_task, \t1, \t2
+ mcr p15, 0, \t1, c13, c0, 3 @ store in TPIDRURO
+.L0_\@:
+#endif
+ .endm
+
/*
* Instruction barrier
*/
@@ -566,12 +623,12 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
/*
* mov_l - move a constant value or [relocated] address into a register
*/
- .macro mov_l, dst:req, imm:req
+ .macro mov_l, dst:req, imm:req, cond
.if __LINUX_ARM_ARCH__ < 7
- ldr \dst, =\imm
+ ldr\cond \dst, =\imm
.else
- movw \dst, #:lower16:\imm
- movt \dst, #:upper16:\imm
+ movw\cond \dst, #:lower16:\imm
+ movt\cond \dst, #:upper16:\imm
.endif
.endm
@@ -609,6 +666,78 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
__adldst_l str, \src, \sym, \tmp, \cond
.endm
+ .macro __ldst_va, op, reg, tmp, sym, cond
+#if __LINUX_ARM_ARCH__ >= 7 || \
+ !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+ (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ mov_l \tmp, \sym, \cond
+ \op\cond \reg, [\tmp]
+#else
+ /*
+ * Avoid a literal load, by emitting a sequence of ADD/LDR instructions
+ * with the appropriate relocations. The combined sequence has a range
+ * of -/+ 256 MiB, which should be sufficient for the core kernel and
+ * for modules loaded into the module region.
+ */
+ .globl \sym
+ .reloc .L0_\@, R_ARM_ALU_PC_G0_NC, \sym
+ .reloc .L1_\@, R_ARM_ALU_PC_G1_NC, \sym
+ .reloc .L2_\@, R_ARM_LDR_PC_G2, \sym
+.L0_\@: sub\cond \tmp, pc, #8
+.L1_\@: sub\cond \tmp, \tmp, #4
+.L2_\@: \op\cond \reg, [\tmp, #0]
+#endif
+ .endm
+
+ /*
+ * ldr_va - load a 32-bit word from the virtual address of \sym
+ */
+ .macro ldr_va, rd:req, sym:req, cond
+ __ldst_va ldr, \rd, \rd, \sym, \cond
+ .endm
+
+ /*
+ * str_va - store a 32-bit word to the virtual address of \sym
+ */
+ .macro str_va, rn:req, sym:req, tmp:req, cond
+ __ldst_va str, \rn, \tmp, \sym, \cond
+ .endm
+
+ /*
+ * ldr_this_cpu_armv6 - Load a 32-bit word from the per-CPU variable 'sym',
+ * without using a temp register. Supported in ARM mode
+ * only.
+ */
+ .macro ldr_this_cpu_armv6, rd:req, sym:req
+ this_cpu_offset \rd
+ .globl \sym
+ .reloc .L0_\@, R_ARM_ALU_PC_G0_NC, \sym
+ .reloc .L1_\@, R_ARM_ALU_PC_G1_NC, \sym
+ .reloc .L2_\@, R_ARM_LDR_PC_G2, \sym
+ add \rd, \rd, pc
+.L0_\@: sub \rd, \rd, #4
+.L1_\@: sub \rd, \rd, #0
+.L2_\@: ldr \rd, [\rd, #4]
+ .endm
+
+ /*
+ * ldr_this_cpu - Load a 32-bit word from the per-CPU variable 'sym'
+ * into register 'rd', which may be the stack pointer,
+ * using 't1' and 't2' as general temp registers. These
+ * are permitted to overlap with 'rd' if != sp
+ */
+ .macro ldr_this_cpu, rd:req, sym:req, t1:req, t2:req
+#if __LINUX_ARM_ARCH__ >= 7 || \
+ !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+ (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ this_cpu_offset \t1
+ mov_l \t2, \sym
+ ldr \rd, [\t1, \t2]
+#else
+ ldr_this_cpu_armv6 \rd, \sym
+#endif
+ .endm
+
/*
* rev_l - byte-swap a 32-bit value
*
@@ -626,4 +755,19 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
.endif
.endm
+ /*
+ * bl_r - branch and link to register
+ *
+ * @dst: target to branch to
+ * @c: conditional opcode suffix
+ */
+ .macro bl_r, dst:req, c
+ .if __LINUX_ARM_ARCH__ < 6
+ mov\c lr, pc
+ mov\c pc, \dst
+ .else
+ blx\c \dst
+ .endif
+ .endm
+
#endif /* __ASM_ASSEMBLER_H__ */
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 5e56288e343b..a094f964c869 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -445,15 +445,10 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
* however some exceptions may exist. Caveat emptor.
*
* - The clobber list is dictated by the call to v7_flush_dcache_*.
- * fp is preserved to the stack explicitly prior disabling the cache
- * since adding it to the clobber list is incompatible with having
- * CONFIG_FRAME_POINTER=y. ip is saved as well if ever r12-clobbering
- * trampoline are inserted by the linker and to keep sp 64-bit aligned.
*/
#define v7_exit_coherency_flush(level) \
asm volatile( \
".arch armv7-a \n\t" \
- "stmfd sp!, {fp, ip} \n\t" \
"mrc p15, 0, r0, c1, c0, 0 @ get SCTLR \n\t" \
"bic r0, r0, #"__stringify(CR_C)" \n\t" \
"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR \n\t" \
@@ -463,10 +458,9 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
"bic r0, r0, #(1 << 6) @ disable local coherency \n\t" \
"mcr p15, 0, r0, c1, c0, 1 @ set ACTLR \n\t" \
"isb \n\t" \
- "dsb \n\t" \
- "ldmfd sp!, {fp, ip}" \
- : : : "r0","r1","r2","r3","r4","r5","r6","r7", \
- "r9","r10","lr","memory" )
+ "dsb" \
+ : : : "r0","r1","r2","r3","r4","r5","r6", \
+ "r9","r10","ip","lr","memory" )
void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
void *kaddr, unsigned long len);
diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
index 6bf0aad672c3..1e1178bf176d 100644
--- a/arch/arm/include/asm/current.h
+++ b/arch/arm/include/asm/current.h
@@ -8,25 +8,18 @@
#define _ASM_ARM_CURRENT_H
#ifndef __ASSEMBLY__
+#include <asm/insn.h>
struct task_struct;
-static inline void set_current(struct task_struct *cur)
-{
- if (!IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO))
- return;
-
- /* Set TPIDRURO */
- asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory");
-}
-
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+extern struct task_struct *__current;
-static inline struct task_struct *get_current(void)
+static __always_inline __attribute_const__ struct task_struct *get_current(void)
{
struct task_struct *cur;
#if __has_builtin(__builtin_thread_pointer) && \
+ defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) && \
!(defined(CONFIG_THUMB2_KERNEL) && \
defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 130001)
/*
@@ -39,16 +32,39 @@ static inline struct task_struct *get_current(void)
* https://github.com/ClangBuiltLinux/linux/issues/1485
*/
cur = __builtin_thread_pointer();
+#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+ asm("0: mrc p15, 0, %0, c13, c0, 3 \n\t"
+#ifdef CONFIG_CPU_V6
+ "1: \n\t"
+ " .subsection 1 \n\t"
+#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
+ !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ "2: " LOAD_SYM_ARMV6(%0, __current) " \n\t"
+ " b 1b \n\t"
#else
- asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(cur));
+ "2: ldr %0, 3f \n\t"
+ " ldr %0, [%0] \n\t"
+ " b 1b \n\t"
+ "3: .long __current \n\t"
+#endif
+ " .previous \n\t"
+ " .pushsection \".alt.smp.init\", \"a\" \n\t"
+ " .long 0b - . \n\t"
+ " b . + (2b - 0b) \n\t"
+ " .popsection \n\t"
+#endif
+ : "=r"(cur));
+#elif __LINUX_ARM_ARCH__>= 7 || \
+ !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+ (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ cur = __current;
+#else
+ asm(LOAD_SYM_ARMV6(%0, __current) : "=r"(cur));
#endif
return cur;
}
#define current get_current()
-#else
-#include <asm-generic/current.h>
-#endif /* CONFIG_CURRENT_POINTER_IN_TPIDRURO */
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index b8102a6ddf16..d68101655b74 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -61,6 +61,9 @@ typedef struct user_fp elf_fpregset_t;
#define R_ARM_MOVT_ABS 44
#define R_ARM_MOVW_PREL_NC 45
#define R_ARM_MOVT_PREL 46
+#define R_ARM_ALU_PC_G0_NC 57
+#define R_ARM_ALU_PC_G1_NC 59
+#define R_ARM_LDR_PC_G2 63
#define R_ARM_THM_CALL 10
#define R_ARM_THM_JUMP24 30
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
deleted file mode 100644
index dfc6bfa43012..000000000000
--- a/arch/arm/include/asm/entry-macro-multi.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/assembler.h>
-
-/*
- * Interrupt handling. Preserves r7, r8, r9
- */
- .macro arch_irq_handler_default
- get_irqnr_preamble r6, lr
-1: get_irqnr_and_base r0, r2, r6, lr
- movne r1, sp
- @
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- @
- badrne lr, 1b
- bne asm_do_IRQ
-
-#ifdef CONFIG_SMP
- /*
- * XXX
- *
- * this macro assumes that irqstat (r2) and base (r6) are
- * preserved from get_irqnr_and_base above
- */
- ALT_SMP(test_for_ipi r0, r2, r6, lr)
- ALT_UP_B(9997f)
- movne r1, sp
- badrne lr, 1b
- bne do_IPI
-#endif
-9997:
- .endm
-
- .macro arch_irq_handler, symbol_name
- .align 5
- .global \symbol_name
-\symbol_name:
- mov r8, lr
- arch_irq_handler_default
- ret r8
- .endm
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index a4dbac07e4ef..7e9251ca29fe 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -2,6 +2,8 @@
#ifndef _ASM_ARM_FTRACE
#define _ASM_ARM_FTRACE
+#define HAVE_FUNCTION_GRAPH_FP_TEST
+
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
#define ARCH_SUPPORTS_FTRACE_OPS 1
#endif
@@ -48,7 +50,7 @@ void *return_address(unsigned int);
static inline void *return_address(unsigned int level)
{
- return NULL;
+ return NULL;
}
#endif
diff --git a/arch/arm/include/asm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S
deleted file mode 100644
index f7692731e514..000000000000
--- a/arch/arm/include/asm/hardware/entry-macro-iomd.S
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * arch/arm/include/asm/hardware/entry-macro-iomd.S
- *
- * Low-level IRQ helper macros for IOC/IOMD based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-/* IOC / IOMD based hardware */
-#include <asm/hardware/iomd.h>
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldrb \irqstat, [\base, #IOMD_IRQREQB] @ get high priority first
- ldr \tmp, =irq_prio_h
- teq \irqstat, #0
-#ifdef IOMD_BASE
- ldrbeq \irqstat, [\base, #IOMD_DMAREQ] @ get dma
- addeq \tmp, \tmp, #256 @ irq_prio_h table size
- teqeq \irqstat, #0
- bne 2406f
-#endif
- ldrbeq \irqstat, [\base, #IOMD_IRQREQA] @ get low priority
- addeq \tmp, \tmp, #256 @ irq_prio_d table size
- teqeq \irqstat, #0
-#ifdef IOMD_IRQREQC
- ldrbeq \irqstat, [\base, #IOMD_IRQREQC]
- addeq \tmp, \tmp, #256 @ irq_prio_l table size
- teqeq \irqstat, #0
-#endif
-#ifdef IOMD_IRQREQD
- ldrbeq \irqstat, [\base, #IOMD_IRQREQD]
- addeq \tmp, \tmp, #256 @ irq_prio_lc table size
- teqeq \irqstat, #0
-#endif
-2406: ldrbne \irqnr, [\tmp, \irqstat] @ get IRQ number
- .endm
-
-/*
- * Interrupt table (incorporates priority). Please note that we
- * rely on the order of these tables (see above code).
- */
- .align 5
-irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-#ifdef IOMD_BASE
-irq_prio_d: .byte 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-#endif
-irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-#ifdef IOMD_IRQREQC
-irq_prio_lc: .byte 24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
- .byte 28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
- .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-#endif
-#ifdef IOMD_IRQREQD
-irq_prio_ld: .byte 40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
- .byte 44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
- .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-#endif
-
diff --git a/arch/arm/include/asm/insn.h b/arch/arm/include/asm/insn.h
index 5475cbf9fb6b..faf3d1c28368 100644
--- a/arch/arm/include/asm/insn.h
+++ b/arch/arm/include/asm/insn.h
@@ -2,6 +2,23 @@
#ifndef __ASM_ARM_INSN_H
#define __ASM_ARM_INSN_H
+#include <linux/types.h>
+
+/*
+ * Avoid a literal load by emitting a sequence of ADD/LDR instructions with the
+ * appropriate relocations. The combined sequence has a range of -/+ 256 MiB,
+ * which should be sufficient for the core kernel as well as modules loaded
+ * into the module region. (Not supported by LLD before release 14)
+ */
+#define LOAD_SYM_ARMV6(reg, sym) \
+ " .globl " #sym " \n\t" \
+ " .reloc 10f, R_ARM_ALU_PC_G0_NC, " #sym " \n\t" \
+ " .reloc 11f, R_ARM_ALU_PC_G1_NC, " #sym " \n\t" \
+ " .reloc 12f, R_ARM_LDR_PC_G2, " #sym " \n\t" \
+ "10: sub " #reg ", pc, #8 \n\t" \
+ "11: sub " #reg ", " #reg ", #4 \n\t" \
+ "12: ldr " #reg ", [" #reg ", #0] \n\t"
+
static inline unsigned long
arm_gen_nop(void)
{
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 1cbcc462b07e..a7c2337b0c7d 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -26,7 +26,6 @@
struct irqaction;
struct pt_regs;
-extern void asm_do_IRQ(unsigned int, struct pt_regs *);
void handle_IRQ(unsigned int, struct pt_regs *);
void init_IRQ(void);
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index eec0c0bda766..9349e7a82c9c 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -56,9 +56,7 @@ struct machine_desc {
void (*init_time)(void);
void (*init_machine)(void);
void (*init_late)(void);
-#ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
void (*handle_irq)(struct pt_regs *);
-#endif
void (*restart)(enum reboot_mode, const char *);
};
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 1592a4264488..e049723840d3 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -10,7 +10,7 @@ typedef struct {
#else
int switch_pending;
#endif
- unsigned int vmalloc_seq;
+ atomic_t vmalloc_seq;
unsigned long sigpage;
#ifdef CONFIG_VDSO
unsigned long vdso;
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 84e58956fcab..db2cb06aa8cf 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -23,6 +23,16 @@
void __check_vmalloc_seq(struct mm_struct *mm);
+#ifdef CONFIG_MMU
+static inline void check_vmalloc_seq(struct mm_struct *mm)
+{
+ if (!IS_ENABLED(CONFIG_ARM_LPAE) &&
+ unlikely(atomic_read(&mm->context.vmalloc_seq) !=
+ atomic_read(&init_mm.context.vmalloc_seq)))
+ __check_vmalloc_seq(mm);
+}
+#endif
+
#ifdef CONFIG_CPU_HAS_ASID
void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
@@ -52,8 +62,7 @@ static inline void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
static inline void check_and_switch_context(struct mm_struct *mm,
struct task_struct *tsk)
{
- if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
- __check_vmalloc_seq(mm);
+ check_vmalloc_seq(mm);
if (irqs_disabled())
/*
@@ -129,6 +138,15 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
#endif
}
+#ifdef CONFIG_VMAP_STACK
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+ if (mm != &init_mm)
+ check_vmalloc_seq(mm);
+}
+#define enter_lazy_tlb enter_lazy_tlb
+#endif
+
#include <asm-generic/mmu_context.h>
#endif
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 11b058a72a5b..5fcc8a600e36 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -147,6 +147,9 @@ extern void copy_page(void *to, const void *from);
#include <asm/pgtable-3level-types.h>
#else
#include <asm/pgtable-2level-types.h>
+#ifdef CONFIG_VMAP_STACK
+#define ARCH_PAGE_TABLE_SYNC_MASK PGTBL_PMD_MODIFIED
+#endif
#endif
#endif /* CONFIG_MMU */
diff --git a/arch/arm/include/asm/paravirt_api_clock.h b/arch/arm/include/asm/paravirt_api_clock.h
new file mode 100644
index 000000000000..65ac7cee0dad
--- /dev/null
+++ b/arch/arm/include/asm/paravirt_api_clock.h
@@ -0,0 +1 @@
+#include <asm/paravirt.h>
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
index e2fcb3cfd3de..7545c87c251f 100644
--- a/arch/arm/include/asm/percpu.h
+++ b/arch/arm/include/asm/percpu.h
@@ -5,20 +5,27 @@
#ifndef _ASM_ARM_PERCPU_H_
#define _ASM_ARM_PERCPU_H_
+#include <asm/insn.h>
+
register unsigned long current_stack_pointer asm ("sp");
/*
* Same as asm-generic/percpu.h, except that we store the per cpu offset
* in the TPIDRPRW. TPIDRPRW only exists on V6K and V7
*/
-#if defined(CONFIG_SMP) && !defined(CONFIG_CPU_V6)
+#ifdef CONFIG_SMP
static inline void set_my_cpu_offset(unsigned long off)
{
+ extern unsigned int smp_on_up;
+
+ if (IS_ENABLED(CONFIG_CPU_V6) && !smp_on_up)
+ return;
+
/* Set TPIDRPRW */
asm volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (off) : "memory");
}
-static inline unsigned long __my_cpu_offset(void)
+static __always_inline unsigned long __my_cpu_offset(void)
{
unsigned long off;
@@ -27,8 +34,28 @@ static inline unsigned long __my_cpu_offset(void)
* We want to allow caching the value, so avoid using volatile and
* instead use a fake stack read to hazard against barrier().
*/
- asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off)
- : "Q" (*(const unsigned long *)current_stack_pointer));
+ asm("0: mrc p15, 0, %0, c13, c0, 4 \n\t"
+#ifdef CONFIG_CPU_V6
+ "1: \n\t"
+ " .subsection 1 \n\t"
+#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
+ !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+ "2: " LOAD_SYM_ARMV6(%0, __per_cpu_offset) " \n\t"
+ " b 1b \n\t"
+#else
+ "2: ldr %0, 3f \n\t"
+ " ldr %0, [%0] \n\t"
+ " b 1b \n\t"
+ "3: .long __per_cpu_offset \n\t"
+#endif
+ " .previous \n\t"
+ " .pushsection \".alt.smp.init\", \"a\" \n\t"
+ " .long 0b - . \n\t"
+ " b . + (2b - 0b) \n\t"
+ " .popsection \n\t"
+#endif
+ : "=r" (off)
+ : "Q" (*(const unsigned long *)current_stack_pointer));
return off;
}
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index 70fe69bdcce2..92abd4cd8ca2 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -208,6 +208,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
}
#define pmd_offset pmd_offset
+#define pmd_pfn(pmd) (__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
+
#define pmd_large(pmd) (pmd_val(pmd) & 2)
#define pmd_leaf(pmd) (pmd_val(pmd) & 2)
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index f16cbbd5cda4..7c1c90d9f582 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -25,11 +25,6 @@ struct seq_file;
extern void show_ipi_list(struct seq_file *, int);
/*
- * Called from assembly code, this handles an IPI.
- */
-asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
-
-/*
* Called from C code, this handles an IPI.
*/
void handle_IPI(int ipinr, struct pt_regs *regs);
diff --git a/arch/arm/include/asm/spectre.h b/arch/arm/include/asm/spectre.h
new file mode 100644
index 000000000000..85f9e538fb32
--- /dev/null
+++ b/arch/arm/include/asm/spectre.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ASM_SPECTRE_H
+#define __ASM_SPECTRE_H
+
+enum {
+ SPECTRE_UNAFFECTED,
+ SPECTRE_MITIGATED,
+ SPECTRE_VULNERABLE,
+};
+
+enum {
+ __SPECTRE_V2_METHOD_BPIALL,
+ __SPECTRE_V2_METHOD_ICIALLU,
+ __SPECTRE_V2_METHOD_SMC,
+ __SPECTRE_V2_METHOD_HVC,
+ __SPECTRE_V2_METHOD_LOOP8,
+};
+
+enum {
+ SPECTRE_V2_METHOD_BPIALL = BIT(__SPECTRE_V2_METHOD_BPIALL),
+ SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU),
+ SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC),
+ SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC),
+ SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8),
+};
+
+#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
+void spectre_v2_update_state(unsigned int state, unsigned int methods);
+#else
+static inline void spectre_v2_update_state(unsigned int state,
+ unsigned int methods)
+{}
+#endif
+
+int spectre_bhb_update_vectors(unsigned int method);
+
+#endif
diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
index 8f54f9ad8a9b..3e78f921b8b2 100644
--- a/arch/arm/include/asm/stacktrace.h
+++ b/arch/arm/include/asm/stacktrace.h
@@ -14,6 +14,9 @@ struct stackframe {
unsigned long sp;
unsigned long lr;
unsigned long pc;
+
+ /* address of the LR value on the stack */
+ unsigned long *lr_addr;
#ifdef CONFIG_KRETPROBES
struct llist_node *kr_cur;
struct task_struct *tsk;
@@ -36,5 +39,7 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
extern int unwind_frame(struct stackframe *frame);
extern void walk_stackframe(struct stackframe *frame,
int (*fn)(struct stackframe *, void *), void *data);
+extern void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+ unsigned long top);
#endif /* __ASM_STACKTRACE_H */
diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h
index 61e4a3c4ca6e..9372348516ce 100644
--- a/arch/arm/include/asm/switch_to.h
+++ b/arch/arm/include/asm/switch_to.h
@@ -3,6 +3,7 @@
#define __ASM_ARM_SWITCH_TO_H
#include <linux/thread_info.h>
+#include <asm/smp_plat.h>
/*
* For v7 SMP cores running a preemptible kernel we may be pre-empted
@@ -26,7 +27,7 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info
#define switch_to(prev,next,last) \
do { \
__complete_pending_tlbi(); \
- if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO)) \
+ if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || is_smp()) \
__this_cpu_write(__entry_task, next); \
last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \
} while (0)
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 164e15f26485..aecc403b2880 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -25,6 +25,14 @@
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define THREAD_START_SP (THREAD_SIZE - 8)
+#ifdef CONFIG_VMAP_STACK
+#define THREAD_ALIGN (2 * THREAD_SIZE)
+#else
+#define THREAD_ALIGN THREAD_SIZE
+#endif
+
+#define OVERFLOW_STACK_SIZE SZ_4K
+
#ifndef __ASSEMBLY__
struct task_struct;
@@ -54,9 +62,6 @@ struct cpu_context_save {
struct thread_info {
unsigned long flags; /* low level flags */
int preempt_count; /* 0 => preemptable, <0 => bug */
-#ifndef CONFIG_THREAD_INFO_IN_TASK
- struct task_struct *task; /* main task structure */
-#endif
__u32 cpu; /* cpu */
__u32 cpu_domain; /* cpu domain */
struct cpu_context_save cpu_context; /* cpu context */
@@ -72,39 +77,15 @@ struct thread_info {
#define INIT_THREAD_INFO(tsk) \
{ \
- INIT_THREAD_INFO_TASK(tsk) \
.flags = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
}
-#ifdef CONFIG_THREAD_INFO_IN_TASK
-#define INIT_THREAD_INFO_TASK(tsk)
-
static inline struct task_struct *thread_task(struct thread_info* ti)
{
return (struct task_struct *)ti;
}
-#else
-#define INIT_THREAD_INFO_TASK(tsk) .task = &(tsk),
-
-static inline struct task_struct *thread_task(struct thread_info* ti)
-{
- return ti->task;
-}
-
-/*
- * how to get the thread information struct from C
- */
-static inline struct thread_info *current_thread_info(void) __attribute_const__;
-
-static inline struct thread_info *current_thread_info(void)
-{
- return (struct thread_info *)
- (current_stack_pointer & ~(THREAD_SIZE - 1));
-}
-#endif
-
#define thread_saved_pc(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
#define thread_saved_sp(tsk) \
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
index c3296499176c..3dcd0f71a0da 100644
--- a/arch/arm/include/asm/tls.h
+++ b/arch/arm/include/asm/tls.h
@@ -18,21 +18,32 @@
.endm
.macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
- ldr \tmp1, =elf_hwcap
- ldr \tmp1, [\tmp1, #0]
+#ifdef CONFIG_SMP
+ALT_SMP(nop)
+ALT_UP_B(.L0_\@)
+ .subsection 1
+#endif
+.L0_\@:
+ ldr_va \tmp1, elf_hwcap
mov \tmp2, #0xffff0fff
tst \tmp1, #HWCAP_TLS @ hardware TLS available?
streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
- mrcne p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
- mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
- mcrne p15, 0, \tpuser, c13, c0, 2 @ set user r/w register
- strne \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
+ beq .L2_\@
+ mcr p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
+#ifdef CONFIG_SMP
+ b .L1_\@
+ .previous
+#endif
+.L1_\@: switch_tls_v6k \base, \tp, \tpuser, \tmp1, \tmp2
+.L2_\@:
.endm
.macro switch_tls_software, base, tp, tpuser, tmp1, tmp2
mov \tmp1, #0xffff0fff
str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0
.endm
+#else
+#include <asm/smp_plat.h>
#endif
#ifdef CONFIG_TLS_REG_EMUL
@@ -43,7 +54,7 @@
#elif defined(CONFIG_CPU_V6)
#define tls_emu 0
#define has_tls_reg (elf_hwcap & HWCAP_TLS)
-#define defer_tls_reg_update 0
+#define defer_tls_reg_update is_smp()
#define switch_tls switch_tls_v6
#elif defined(CONFIG_CPU_32v6K)
#define tls_emu 0
@@ -81,11 +92,11 @@ static inline void set_tls(unsigned long val)
*/
barrier();
- if (!tls_emu && !defer_tls_reg_update) {
- if (has_tls_reg) {
+ if (!tls_emu) {
+ if (has_tls_reg && !defer_tls_reg_update) {
asm("mcr p15, 0, %0, c13, c0, 3"
: : "r" (val));
- } else {
+ } else if (!has_tls_reg) {
#ifdef CONFIG_KUSER_HELPERS
/*
* User space must never try to access this
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 32dbfd81f42a..2fcbec9c306c 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -56,21 +56,6 @@ extern int __put_user_bad(void);
#ifdef CONFIG_MMU
/*
- * We use 33-bit arithmetic here. Success returns zero, failure returns
- * addr_limit. We take advantage that addr_limit will be zero for KERNEL_DS,
- * so this will always return success in that case.
- */
-#define __range_ok(addr, size) ({ \
- unsigned long flag, roksum; \
- __chk_user_ptr(addr); \
- __asm__(".syntax unified\n" \
- "adds %1, %2, %3; sbcscc %1, %1, %0; movcc %0, #0" \
- : "=&r" (flag), "=&r" (roksum) \
- : "r" (addr), "Ir" (size), "0" (TASK_SIZE) \
- : "cc"); \
- flag; })
-
-/*
* This is a type: either unsigned long, if the argument fits into
* that type, or otherwise unsigned long long.
*/
@@ -241,15 +226,12 @@ extern int __put_user_8(void *, unsigned long long);
#else /* CONFIG_MMU */
-#define __addr_ok(addr) ((void)(addr), 1)
-#define __range_ok(addr, size) ((void)(addr), 0)
-
#define get_user(x, p) __get_user(x, p)
#define __put_user_check __put_user_nocheck
#endif /* CONFIG_MMU */
-#define access_ok(addr, size) (__range_ok(addr, size) == 0)
+#include <asm-generic/access_ok.h>
#ifdef CONFIG_CPU_SPECTRE
/*
@@ -476,8 +458,6 @@ do { \
: "r" (x), "i" (-EFAULT) \
: "cc")
-#define HAVE_GET_KERNEL_NOFAULT
-
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
const type *__pk_ptr = (src); \
diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h
index 2cb00d15831b..4512f7e1918f 100644
--- a/arch/arm/include/asm/v7m.h
+++ b/arch/arm/include/asm/v7m.h
@@ -13,6 +13,7 @@
#define V7M_SCB_ICSR_PENDSVSET (1 << 28)
#define V7M_SCB_ICSR_PENDSVCLR (1 << 27)
#define V7M_SCB_ICSR_RETTOBASE (1 << 11)
+#define V7M_SCB_ICSR_VECTACTIVE 0x000001ff
#define V7M_SCB_VTOR 0x08
@@ -38,7 +39,7 @@
#define V7M_SCB_SHCSR_MEMFAULTENA (1 << 16)
#define V7M_xPSR_FRAMEPTRALIGN 0x00000200
-#define V7M_xPSR_EXCEPTIONNO 0x000001ff
+#define V7M_xPSR_EXCEPTIONNO V7M_SCB_ICSR_VECTACTIVE
/*
* When branching to an address that has bits [31:28] == 0xf an exception return
diff --git a/arch/arm/include/asm/vmlinux.lds.h b/arch/arm/include/asm/vmlinux.lds.h
index 4a91428c324d..fad45c884e98 100644
--- a/arch/arm/include/asm/vmlinux.lds.h
+++ b/arch/arm/include/asm/vmlinux.lds.h
@@ -26,6 +26,19 @@
#define ARM_MMU_DISCARD(x) x
#endif
+/*
+ * ld.lld does not support NOCROSSREFS:
+ * https://github.com/ClangBuiltLinux/linux/issues/1609
+ */
+#ifdef CONFIG_LD_IS_LLD
+#define NOCROSSREFS
+#endif
+
+/* Set start/end symbol names to the LMA for the section */
+#define ARM_LMA(sym, section) \
+ sym##_start = LOADADDR(section); \
+ sym##_end = LOADADDR(section) + SIZEOF(section)
+
#define PROC_INFO \
. = ALIGN(4); \
__proc_info_begin = .; \
@@ -110,19 +123,31 @@
* only thing that matters is their relative offsets
*/
#define ARM_VECTORS \
- __vectors_start = .; \
- .vectors 0xffff0000 : AT(__vectors_start) { \
- *(.vectors) \
+ __vectors_lma = .; \
+ OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \
+ .vectors { \
+ *(.vectors) \
+ } \
+ .vectors.bhb.loop8 { \
+ *(.vectors.bhb.loop8) \
+ } \
+ .vectors.bhb.bpiall { \
+ *(.vectors.bhb.bpiall) \
+ } \
} \
- . = __vectors_start + SIZEOF(.vectors); \
- __vectors_end = .; \
+ ARM_LMA(__vectors, .vectors); \
+ ARM_LMA(__vectors_bhb_loop8, .vectors.bhb.loop8); \
+ ARM_LMA(__vectors_bhb_bpiall, .vectors.bhb.bpiall); \
+ . = __vectors_lma + SIZEOF(.vectors) + \
+ SIZEOF(.vectors.bhb.loop8) + \
+ SIZEOF(.vectors.bhb.bpiall); \
\
- __stubs_start = .; \
- .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { \
+ __stubs_lma = .; \
+ .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \
*(.stubs) \
} \
- . = __stubs_start + SIZEOF(.stubs); \
- __stubs_end = .; \
+ ARM_LMA(__stubs, .stubs); \
+ . = __stubs_lma + SIZEOF(.stubs); \
\
PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
diff --git a/arch/arm/include/asm/xor.h b/arch/arm/include/asm/xor.h
index aefddec79286..669cad5194d3 100644
--- a/arch/arm/include/asm/xor.h
+++ b/arch/arm/include/asm/xor.h
@@ -44,7 +44,8 @@
: "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
static void
-xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_arm4regs_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
unsigned int lines = bytes / sizeof(unsigned long) / 4;
register unsigned int a1 __asm__("r4");
@@ -64,8 +65,9 @@ xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_arm4regs_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
unsigned int lines = bytes / sizeof(unsigned long) / 4;
register unsigned int a1 __asm__("r4");
@@ -86,8 +88,10 @@ xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_arm4regs_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
unsigned int lines = bytes / sizeof(unsigned long) / 2;
register unsigned int a1 __asm__("r8");
@@ -105,8 +109,11 @@ xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_arm4regs_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
unsigned int lines = bytes / sizeof(unsigned long) / 2;
register unsigned int a1 __asm__("r8");
@@ -146,7 +153,8 @@ static struct xor_block_template xor_block_arm4regs = {
extern struct xor_block_template const xor_block_neon_inner;
static void
-xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+xor_neon_2(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2)
{
if (in_interrupt()) {
xor_arm4regs_2(bytes, p1, p2);
@@ -158,8 +166,9 @@ xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
}
static void
-xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3)
+xor_neon_3(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3)
{
if (in_interrupt()) {
xor_arm4regs_3(bytes, p1, p2, p3);
@@ -171,8 +180,10 @@ xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4)
+xor_neon_4(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4)
{
if (in_interrupt()) {
xor_arm4regs_4(bytes, p1, p2, p3, p4);
@@ -184,8 +195,11 @@ xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
}
static void
-xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
- unsigned long *p3, unsigned long *p4, unsigned long *p5)
+xor_neon_5(unsigned long bytes, unsigned long * __restrict p1,
+ const unsigned long * __restrict p2,
+ const unsigned long * __restrict p3,
+ const unsigned long * __restrict p4,
+ const unsigned long * __restrict p5)
{
if (in_interrupt()) {
xor_arm4regs_5(bytes, p1, p2, p3, p4, p5);
diff --git a/arch/arm/include/uapi/asm/signal.h b/arch/arm/include/uapi/asm/signal.h
index c9a3ea1d8d41..9e2178420db2 100644
--- a/arch/arm/include/uapi/asm/signal.h
+++ b/arch/arm/include/uapi/asm/signal.h
@@ -93,7 +93,7 @@ struct sigaction {
typedef struct sigaltstack {
void __user *ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index ae295a3bcfef..553866751e1a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -10,6 +10,7 @@ ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_insn.o = -pg
CFLAGS_REMOVE_patch.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
endif
CFLAGS_REMOVE_return_address.o = -pg
@@ -106,4 +107,6 @@ endif
obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o
+obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o
+
extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 645845e4982a..2c8d76fd7c66 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -43,9 +43,6 @@ int main(void)
BLANK();
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
-#ifndef CONFIG_THREAD_INFO_IN_TASK
- DEFINE(TI_TASK, offsetof(struct thread_info, task));
-#endif
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain));
DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context));
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 5cd057859fe9..06508698abb8 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -19,9 +19,6 @@
#include <asm/glue-df.h>
#include <asm/glue-pf.h>
#include <asm/vfpmacros.h>
-#ifndef CONFIG_GENERIC_IRQ_MULTI_HANDLER
-#include <mach/entry-macro.S>
-#endif
#include <asm/thread_notify.h>
#include <asm/unwind.h>
#include <asm/unistd.h>
@@ -30,19 +27,35 @@
#include <asm/uaccess-asm.h>
#include "entry-header.S"
-#include <asm/entry-macro-multi.S>
#include <asm/probes.h>
/*
* Interrupt handling.
*/
- .macro irq_handler
-#ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
- mov r0, sp
- bl generic_handle_arch_irq
-#else
- arch_irq_handler_default
+ .macro irq_handler, from_user:req
+ mov r1, sp
+ ldr_this_cpu r2, irq_stack_ptr, r2, r3
+ .if \from_user == 0
+ @
+ @ If we took the interrupt while running in the kernel, we may already
+ @ be using the IRQ stack, so revert to the original value in that case.
+ @
+ subs r3, r2, r1 @ SP above bottom of IRQ stack?
+ rsbscs r3, r3, #THREAD_SIZE @ ... and below the top?
+#ifdef CONFIG_VMAP_STACK
+ ldr_va r3, high_memory, cc @ End of the linear region
+ cmpcc r3, r1 @ Stack pointer was below it?
#endif
+ bcc 0f @ If not, switch to the IRQ stack
+ mov r0, r1
+ bl generic_handle_arch_irq
+ b 1f
+0:
+ .endif
+
+ mov_l r0, generic_handle_arch_irq
+ bl call_with_stack
+1:
.endm
.macro pabt_helper
@@ -140,27 +153,35 @@ ENDPROC(__und_invalid)
#define SPFIX(code...)
#endif
- .macro svc_entry, stack_hole=0, trace=1, uaccess=1
+ .macro svc_entry, stack_hole=0, trace=1, uaccess=1, overflow_check=1
UNWIND(.fnstart )
- UNWIND(.save {r0 - pc} )
- sub sp, sp, #(SVC_REGS_SIZE + \stack_hole - 4)
+ sub sp, sp, #(SVC_REGS_SIZE + \stack_hole)
+ THUMB( add sp, r1 ) @ get SP in a GPR without
+ THUMB( sub r1, sp, r1 ) @ using a temp register
+
+ .if \overflow_check
+ UNWIND(.save {r0 - pc} )
+ do_overflow_check (SVC_REGS_SIZE + \stack_hole)
+ .endif
+
#ifdef CONFIG_THUMB2_KERNEL
- SPFIX( str r0, [sp] ) @ temporarily saved
- SPFIX( mov r0, sp )
- SPFIX( tst r0, #4 ) @ test original stack alignment
- SPFIX( ldr r0, [sp] ) @ restored
+ tst r1, #4 @ test stack pointer alignment
+ sub r1, sp, r1 @ restore original R1
+ sub sp, r1 @ restore original SP
#else
SPFIX( tst sp, #4 )
#endif
- SPFIX( subeq sp, sp, #4 )
- stmia sp, {r1 - r12}
+ SPFIX( subne sp, sp, #4 )
+
+ ARM( stmib sp, {r1 - r12} )
+ THUMB( stmia sp, {r0 - r12} ) @ No STMIB in Thumb-2
ldmia r0, {r3 - r5}
- add r7, sp, #S_SP - 4 @ here for interlock avoidance
+ add r7, sp, #S_SP @ here for interlock avoidance
mov r6, #-1 @ "" "" "" ""
- add r2, sp, #(SVC_REGS_SIZE + \stack_hole - 4)
- SPFIX( addeq r2, r2, #4 )
- str r3, [sp, #-4]! @ save the "real" r0 copied
+ add r2, sp, #(SVC_REGS_SIZE + \stack_hole)
+ SPFIX( addne r2, r2, #4 )
+ str r3, [sp] @ save the "real" r0 copied
@ from the exception stack
mov r3, lr
@@ -199,7 +220,7 @@ ENDPROC(__dabt_svc)
.align 5
__irq_svc:
svc_entry
- irq_handler
+ irq_handler from_user=0
#ifdef CONFIG_PREEMPTION
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -426,7 +447,7 @@ ENDPROC(__dabt_usr)
__irq_usr:
usr_entry
kuser_cmpxchg_check
- irq_handler
+ irq_handler from_user=1
get_thread_info tsk
mov why, #0
b ret_to_user_from_irq
@@ -752,16 +773,17 @@ ENTRY(__switch_to)
ldr r6, [r2, #TI_CPU_DOMAIN]
#endif
switch_tls r1, r4, r5, r3, r7
-#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
- ldr r7, [r2, #TI_TASK]
+#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
+ !defined(CONFIG_STACKPROTECTOR_PER_TASK)
ldr r8, =__stack_chk_guard
.if (TSK_STACK_CANARY > IMM12_MASK)
- add r7, r7, #TSK_STACK_CANARY & ~IMM12_MASK
+ add r9, r2, #TSK_STACK_CANARY & ~IMM12_MASK
+ ldr r9, [r9, #TSK_STACK_CANARY & IMM12_MASK]
+ .else
+ ldr r9, [r2, #TSK_STACK_CANARY & IMM12_MASK]
.endif
- ldr r7, [r7, #TSK_STACK_CANARY & IMM12_MASK]
-#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO)
- mov r7, r2 @ Preserve 'next'
#endif
+ mov r7, r2 @ Preserve 'next'
#ifdef CONFIG_CPU_USE_DOMAINS
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
#endif
@@ -770,19 +792,102 @@ ENTRY(__switch_to)
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
-#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
- str r7, [r8]
+#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
+ !defined(CONFIG_STACKPROTECTOR_PER_TASK)
+ str r9, [r8]
#endif
- THUMB( mov ip, r4 )
mov r0, r5
- set_current r7
- ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously
- THUMB( ldmia ip!, {r4 - sl, fp} ) @ Load all regs saved previously
- THUMB( ldr sp, [ip], #4 )
- THUMB( ldr pc, [ip] )
+#if !defined(CONFIG_THUMB2_KERNEL) && !defined(CONFIG_VMAP_STACK)
+ set_current r7, r8
+ ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
+#else
+ mov r1, r7
+ ldmia r4, {r4 - sl, fp, ip, lr} @ Load all regs saved previously
+#ifdef CONFIG_VMAP_STACK
+ @
+ @ Do a dummy read from the new stack while running from the old one so
+ @ that we can rely on do_translation_fault() to fix up any stale PMD
+ @ entries covering the vmalloc region.
+ @
+ ldr r2, [ip]
+#endif
+
+ @ When CONFIG_THREAD_INFO_IN_TASK=n, the update of SP itself is what
+ @ effectuates the task switch, as that is what causes the observable
+ @ values of current and current_thread_info to change. When
+ @ CONFIG_THREAD_INFO_IN_TASK=y, setting current (and therefore
+ @ current_thread_info) is done explicitly, and the update of SP just
+ @ switches us to another stack, with few other side effects. In order
+ @ to prevent this distinction from causing any inconsistencies, let's
+ @ keep the 'set_current' call as close as we can to the update of SP.
+ set_current r1, r2
+ mov sp, ip
+ ret lr
+#endif
UNWIND(.fnend )
ENDPROC(__switch_to)
+#ifdef CONFIG_VMAP_STACK
+ .text
+ .align 2
+__bad_stack:
+ @
+ @ We've just detected an overflow. We need to load the address of this
+ @ CPU's overflow stack into the stack pointer register. We have only one
+ @ scratch register so let's use a sequence of ADDs including one
+ @ involving the PC, and decorate them with PC-relative group
+ @ relocations. As these are ARM only, switch to ARM mode first.
+ @
+ @ We enter here with IP clobbered and its value stashed on the mode
+ @ stack.
+ @
+THUMB( bx pc )
+THUMB( nop )
+THUMB( .arm )
+ ldr_this_cpu_armv6 ip, overflow_stack_ptr
+
+ str sp, [ip, #-4]! @ Preserve original SP value
+ mov sp, ip @ Switch to overflow stack
+ pop {ip} @ Original SP in IP
+
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+ mov ip, ip @ mov expected by unwinder
+ push {fp, ip, lr, pc} @ GCC flavor frame record
+#else
+ str ip, [sp, #-8]! @ store original SP
+ push {fpreg, lr} @ Clang flavor frame record
+#endif
+UNWIND( ldr ip, [r0, #4] ) @ load exception LR
+UNWIND( str ip, [sp, #12] ) @ store in the frame record
+ ldr ip, [r0, #12] @ reload IP
+
+ @ Store the original GPRs to the new stack.
+ svc_entry uaccess=0, overflow_check=0
+
+UNWIND( .save {sp, pc} )
+UNWIND( .save {fpreg, lr} )
+UNWIND( .setfp fpreg, sp )
+
+ ldr fpreg, [sp, #S_SP] @ Add our frame record
+ @ to the linked list
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+ ldr r1, [fp, #4] @ reload SP at entry
+ add fp, fp, #12
+#else
+ ldr r1, [fpreg, #8]
+#endif
+ str r1, [sp, #S_SP] @ store in pt_regs
+
+ @ Stash the regs for handle_bad_stack
+ mov r0, sp
+
+ @ Time to die
+ bl handle_bad_stack
+ nop
+UNWIND( .fnend )
+ENDPROC(__bad_stack)
+#endif
+
__INIT
/*
@@ -1002,12 +1107,11 @@ vector_\name:
sub lr, lr, #\correction
.endif
- @
- @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
- @ (parent CPSR)
- @
+ @ Save r0, lr_<exception> (parent PC)
stmia sp, {r0, lr} @ save r0, lr
- mrs lr, spsr
+
+ @ Save spsr_<exception> (parent CPSR)
+2: mrs lr, spsr
str lr, [sp, #8] @ save spsr
@
@@ -1028,6 +1132,44 @@ vector_\name:
movs pc, lr @ branch to handler in SVC mode
ENDPROC(vector_\name)
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ .subsection 1
+ .align 5
+vector_bhb_loop8_\name:
+ .if \correction
+ sub lr, lr, #\correction
+ .endif
+
+ @ Save r0, lr_<exception> (parent PC)
+ stmia sp, {r0, lr}
+
+ @ bhb workaround
+ mov r0, #8
+3: b . + 4
+ subs r0, r0, #1
+ bne 3b
+ dsb
+ isb
+ b 2b
+ENDPROC(vector_bhb_loop8_\name)
+
+vector_bhb_bpiall_\name:
+ .if \correction
+ sub lr, lr, #\correction
+ .endif
+
+ @ Save r0, lr_<exception> (parent PC)
+ stmia sp, {r0, lr}
+
+ @ bhb workaround
+ mcr p15, 0, r0, c7, c5, 6 @ BPIALL
+ @ isb not needed due to "movs pc, lr" in the vector stub
+ @ which gives a "context synchronisation".
+ b 2b
+ENDPROC(vector_bhb_bpiall_\name)
+ .previous
+#endif
+
.align 2
@ handler addresses follow this label
1:
@@ -1036,6 +1178,10 @@ ENDPROC(vector_\name)
.section .stubs, "ax", %progbits
@ This must be the first word
.word vector_swi
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ .word vector_bhb_loop8_swi
+ .word vector_bhb_bpiall_swi
+#endif
vector_rst:
ARM( swi SYS_ERROR0 )
@@ -1150,8 +1296,10 @@ vector_addrexcptn:
* FIQ "NMI" handler
*-----------------------------------------------------------------------------
* Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86
- * systems.
+ * systems. This must be the last vector stub, so lets place it in its own
+ * subsection.
*/
+ .subsection 2
vector_stub fiq, FIQ_MODE, 4
.long __fiq_usr @ 0 (USR_26 / USR_32)
@@ -1184,6 +1332,30 @@ vector_addrexcptn:
W(b) vector_irq
W(b) vector_fiq
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ .section .vectors.bhb.loop8, "ax", %progbits
+.L__vectors_bhb_loop8_start:
+ W(b) vector_rst
+ W(b) vector_bhb_loop8_und
+ W(ldr) pc, .L__vectors_bhb_loop8_start + 0x1004
+ W(b) vector_bhb_loop8_pabt
+ W(b) vector_bhb_loop8_dabt
+ W(b) vector_addrexcptn
+ W(b) vector_bhb_loop8_irq
+ W(b) vector_bhb_loop8_fiq
+
+ .section .vectors.bhb.bpiall, "ax", %progbits
+.L__vectors_bhb_bpiall_start:
+ W(b) vector_rst
+ W(b) vector_bhb_bpiall_und
+ W(ldr) pc, .L__vectors_bhb_bpiall_start + 0x1008
+ W(b) vector_bhb_bpiall_pabt
+ W(b) vector_bhb_bpiall_dabt
+ W(b) vector_addrexcptn
+ W(b) vector_bhb_bpiall_irq
+ W(b) vector_bhb_bpiall_fiq
+#endif
+
.data
.align 2
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index ac86c34682bb..90d40f4d56cf 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -16,12 +16,14 @@
.equ NR_syscalls, __NR_syscalls
-#ifdef CONFIG_NEED_RET_TO_USER
-#include <mach/entry-macro.S>
-#else
- .macro arch_ret_to_user, tmp1, tmp2
- .endm
+ .macro arch_ret_to_user, tmp
+#ifdef CONFIG_ARCH_IOP32X
+ mrc p15, 0, \tmp, c15, c1, 0
+ tst \tmp, #(1 << 6)
+ bicne \tmp, \tmp, #(1 << 6)
+ mcrne p15, 0, \tmp, c15, c1, 0 @ Disable cp6 access
#endif
+ .endm
#include "entry-header.S"
@@ -55,7 +57,7 @@ __ret_fast_syscall:
/* perform architecture specific actions before user return */
- arch_ret_to_user r1, lr
+ arch_ret_to_user r1
restore_user_regs fast = 1, offset = S_OFF
UNWIND(.fnend )
@@ -128,7 +130,7 @@ no_work_pending:
asm_trace_hardirqs_on save = 0
/* perform architecture specific actions before user return */
- arch_ret_to_user r1, lr
+ arch_ret_to_user r1
ct_user_enter save = 0
restore_user_regs fast = 0, offset = 0
@@ -154,12 +156,36 @@ ENDPROC(ret_from_fork)
*/
.align 5
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ENTRY(vector_bhb_loop8_swi)
+ sub sp, sp, #PT_REGS_SIZE
+ stmia sp, {r0 - r12}
+ mov r8, #8
+1: b 2f
+2: subs r8, r8, #1
+ bne 1b
+ dsb
+ isb
+ b 3f
+ENDPROC(vector_bhb_loop8_swi)
+
+ .align 5
+ENTRY(vector_bhb_bpiall_swi)
+ sub sp, sp, #PT_REGS_SIZE
+ stmia sp, {r0 - r12}
+ mcr p15, 0, r8, c7, c5, 6 @ BPIALL
+ isb
+ b 3f
+ENDPROC(vector_bhb_bpiall_swi)
+#endif
+ .align 5
ENTRY(vector_swi)
#ifdef CONFIG_CPU_V7M
v7m_exception_entry
#else
sub sp, sp, #PT_REGS_SIZE
stmia sp, {r0 - r12} @ Calling r0 - r12
+3:
ARM( add r8, sp, #S_PC )
ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
THUMB( mov r8, sp )
diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index a74289ebc803..3e7bcaca5e07 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -22,12 +22,9 @@
* mcount can be thought of as a function called in the middle of a subroutine
* call. As such, it needs to be transparent for both the caller and the
* callee: the original lr needs to be restored when leaving mcount, and no
- * registers should be clobbered. (In the __gnu_mcount_nc implementation, we
- * clobber the ip register. This is OK because the ARM calling convention
- * allows it to be clobbered in subroutines and doesn't use it to hold
- * parameters.)
+ * registers should be clobbered.
*
- * When using dynamic ftrace, we patch out the mcount call by a "pop {lr}"
+ * When using dynamic ftrace, we patch out the mcount call by a "add sp, #4"
* instead of the __gnu_mcount_nc call (see arch/arm/kernel/ftrace.c).
*/
@@ -38,23 +35,20 @@
.macro __mcount suffix
mcount_enter
- ldr r0, =ftrace_trace_function
- ldr r2, [r0]
- adr r0, .Lftrace_stub
+ ldr_va r2, ftrace_trace_function
+ badr r0, .Lftrace_stub
cmp r0, r2
bne 1f
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- ldr r1, =ftrace_graph_return
- ldr r2, [r1]
- cmp r0, r2
- bne ftrace_graph_caller\suffix
-
- ldr r1, =ftrace_graph_entry
- ldr r2, [r1]
- ldr r0, =ftrace_graph_entry_stub
- cmp r0, r2
- bne ftrace_graph_caller\suffix
+ ldr_va r2, ftrace_graph_return
+ cmp r0, r2
+ bne ftrace_graph_caller\suffix
+
+ ldr_va r2, ftrace_graph_entry
+ mov_l r0, ftrace_graph_entry_stub
+ cmp r0, r2
+ bne ftrace_graph_caller\suffix
#endif
mcount_exit
@@ -70,29 +64,27 @@
.macro __ftrace_regs_caller
- sub sp, sp, #8 @ space for PC and CPSR OLD_R0,
+ str lr, [sp, #-8]! @ store LR as PC and make space for CPSR/OLD_R0,
@ OLD_R0 will overwrite previous LR
- add ip, sp, #12 @ move in IP the value of SP as it was
- @ before the push {lr} of the mcount mechanism
+ ldr lr, [sp, #8] @ get previous LR
- str lr, [sp, #0] @ store LR instead of PC
+ str r0, [sp, #8] @ write r0 as OLD_R0 over previous LR
- ldr lr, [sp, #8] @ get previous LR
+ str lr, [sp, #-4]! @ store previous LR as LR
- str r0, [sp, #8] @ write r0 as OLD_R0 over previous LR
+ add lr, sp, #16 @ move in LR the value of SP as it was
+ @ before the push {lr} of the mcount mechanism
- stmdb sp!, {ip, lr}
- stmdb sp!, {r0-r11, lr}
+ push {r0-r11, ip, lr}
@ stack content at this point:
@ 0 4 48 52 56 60 64 68 72
- @ R0 | R1 | ... | LR | SP + 4 | previous LR | LR | PSR | OLD_R0 |
+ @ R0 | R1 | ... | IP | SP + 4 | previous LR | LR | PSR | OLD_R0 |
- mov r3, sp @ struct pt_regs*
+ mov r3, sp @ struct pt_regs*
- ldr r2, =function_trace_op
- ldr r2, [r2] @ pointer to the current
+ ldr_va r2, function_trace_op @ pointer to the current
@ function tracing op
ldr r1, [sp, #S_LR] @ lr of instrumented func
@@ -108,35 +100,37 @@ ftrace_regs_call:
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_regs_call
ftrace_graph_regs_call:
- mov r0, r0
+ARM( mov r0, r0 )
+THUMB( nop.w )
#endif
@ pop saved regs
- ldmia sp!, {r0-r12} @ restore r0 through r12
- ldr ip, [sp, #8] @ restore PC
- ldr lr, [sp, #4] @ restore LR
- ldr sp, [sp, #0] @ restore SP
- mov pc, ip @ return
+ pop {r0-r11, ip, lr} @ restore r0 through r12
+ ldr lr, [sp], #4 @ restore LR
+ ldr pc, [sp], #12
.endm
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.macro __ftrace_graph_regs_caller
- sub r0, fp, #4 @ lr of instrumented routine (parent)
+#ifdef CONFIG_UNWINDER_FRAME_POINTER
+ sub r0, fp, #4 @ lr of instrumented routine (parent)
+#else
+ add r0, sp, #S_LR
+#endif
@ called from __ftrace_regs_caller
- ldr r1, [sp, #S_PC] @ instrumented routine (func)
+ ldr r1, [sp, #S_PC] @ instrumented routine (func)
mcount_adjust_addr r1, r1
- mov r2, fp @ frame pointer
+ mov r2, fpreg @ frame pointer
+ add r3, sp, #PT_REGS_SIZE
bl prepare_ftrace_return
@ pop registers saved in ftrace_regs_caller
- ldmia sp!, {r0-r12} @ restore r0 through r12
- ldr ip, [sp, #8] @ restore PC
- ldr lr, [sp, #4] @ restore LR
- ldr sp, [sp, #0] @ restore SP
- mov pc, ip @ return
+ pop {r0-r11, ip, lr} @ restore r0 through r12
+ ldr lr, [sp], #4 @ restore LR
+ ldr pc, [sp], #12
.endm
#endif
@@ -149,8 +143,7 @@ ftrace_graph_regs_call:
mcount_adjust_addr r0, lr @ instrumented function
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
- ldr r2, =function_trace_op
- ldr r2, [r2] @ pointer to the current
+ ldr_va r2, function_trace_op @ pointer to the current
@ function tracing op
mov r3, #0 @ regs is NULL
#endif
@@ -162,14 +155,19 @@ ftrace_call\suffix:
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call\suffix
ftrace_graph_call\suffix:
- mov r0, r0
+ARM( mov r0, r0 )
+THUMB( nop.w )
#endif
mcount_exit
.endm
.macro __ftrace_graph_caller
+#ifdef CONFIG_UNWINDER_FRAME_POINTER
sub r0, fp, #4 @ &lr of instrumented routine (&parent)
+#else
+ add r0, sp, #20
+#endif
#ifdef CONFIG_DYNAMIC_FTRACE
@ called from __ftrace_caller, saved in mcount_enter
ldr r1, [sp, #16] @ instrumented routine (func)
@@ -178,7 +176,8 @@ ftrace_graph_call\suffix:
@ called from __mcount, untouched in lr
mcount_adjust_addr r1, lr @ instrumented routine (func)
#endif
- mov r2, fp @ frame pointer
+ mov r2, fpreg @ frame pointer
+ add r3, sp, #24
bl prepare_ftrace_return
mcount_exit
.endm
@@ -202,16 +201,17 @@ ftrace_graph_call\suffix:
.endm
.macro mcount_exit
- ldmia sp!, {r0-r3, ip, lr}
- ret ip
+ ldmia sp!, {r0-r3}
+ ldr lr, [sp, #4]
+ ldr pc, [sp], #8
.endm
ENTRY(__gnu_mcount_nc)
UNWIND(.fnstart)
#ifdef CONFIG_DYNAMIC_FTRACE
- mov ip, lr
- ldmia sp!, {lr}
- ret ip
+ push {lr}
+ ldr lr, [sp, #4]
+ ldr pc, [sp], #8
#else
__mcount
#endif
@@ -256,17 +256,33 @@ ENDPROC(ftrace_graph_regs_caller)
.purgem mcount_exit
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- .globl return_to_handler
-return_to_handler:
+ENTRY(return_to_handler)
stmdb sp!, {r0-r3}
- mov r0, fp @ frame pointer
+ add r0, sp, #16 @ sp at exit of instrumented routine
bl ftrace_return_to_handler
mov lr, r0 @ r0 has real ret addr
ldmia sp!, {r0-r3}
ret lr
+ENDPROC(return_to_handler)
#endif
ENTRY(ftrace_stub)
.Lftrace_stub:
ret lr
ENDPROC(ftrace_stub)
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+ __INIT
+
+ .macro init_tramp, dst:req
+ENTRY(\dst\()_from_init)
+ ldr pc, =\dst
+ENDPROC(\dst\()_from_init)
+ .endm
+
+ init_tramp ftrace_caller
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+ init_tramp ftrace_regs_caller
+#endif
+#endif
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index ae24dd54e9ef..9a1dc142f782 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -292,12 +292,18 @@
.macro restore_user_regs, fast = 0, offset = 0
-#if defined(CONFIG_CPU_32v6K) && !defined(CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_32v6K) && \
+ (!defined(CONFIG_CPU_V6) || defined(CONFIG_SMP))
+#ifdef CONFIG_CPU_V6
+ALT_SMP(nop)
+ALT_UP_B(.L1_\@)
+#endif
@ The TLS register update is deferred until return to user space so we
@ can use it for other things while running in the kernel
- get_thread_info r1
+ mrc p15, 0, r1, c13, c0, 3 @ get current_thread_info pointer
ldr r1, [r1, #TI_TP_VALUE]
mcr p15, 0, r1, c13, c0, 3 @ set TLS register
+.L1_\@:
#endif
uaccess_enable r1, isb=0
@@ -423,3 +429,40 @@ scno .req r7 @ syscall number
tbl .req r8 @ syscall table pointer
why .req r8 @ Linux syscall (!= 0)
tsk .req r9 @ current thread_info
+
+ .macro do_overflow_check, frame_size:req
+#ifdef CONFIG_VMAP_STACK
+ @
+ @ Test whether the SP has overflowed. Task and IRQ stacks are aligned
+ @ so that SP & BIT(THREAD_SIZE_ORDER + PAGE_SHIFT) should always be
+ @ zero.
+ @
+ARM( tst sp, #1 << (THREAD_SIZE_ORDER + PAGE_SHIFT) )
+THUMB( tst r1, #1 << (THREAD_SIZE_ORDER + PAGE_SHIFT) )
+THUMB( it ne )
+ bne .Lstack_overflow_check\@
+
+ .pushsection .text
+.Lstack_overflow_check\@:
+ @
+ @ The stack pointer is not pointing to a valid vmap'ed stack, but it
+ @ may be pointing into the linear map instead, which may happen if we
+ @ are already running from the overflow stack. We cannot detect overflow
+ @ in such cases so just carry on.
+ @
+ str ip, [r0, #12] @ Stash IP on the mode stack
+ ldr_va ip, high_memory @ Start of VMALLOC space
+ARM( cmp sp, ip ) @ SP in vmalloc space?
+THUMB( cmp r1, ip )
+THUMB( itt lo )
+ ldrlo ip, [r0, #12] @ Restore IP
+ blo .Lout\@ @ Carry on
+
+THUMB( sub r1, sp, r1 ) @ Restore original R1
+THUMB( sub sp, r1 ) @ Restore original SP
+ add sp, sp, #\frame_size @ Undo svc_entry's SP change
+ b __bad_stack @ Handle VMAP stack overflow
+ .popsection
+.Lout\@:
+#endif
+ .endm
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 7bde93c10962..de8a60363c85 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -39,16 +39,25 @@ __irq_entry:
@
@ Invoke the IRQ handler
@
- mrs r0, ipsr
- ldr r1, =V7M_xPSR_EXCEPTIONNO
- and r0, r1
- sub r0, #16
- mov r1, sp
- stmdb sp!, {lr}
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- bl nvic_handle_irq
-
- pop {lr}
+ mov r0, sp
+ ldr_this_cpu sp, irq_stack_ptr, r1, r2
+
+ @
+ @ If we took the interrupt while running in the kernel, we may already
+ @ be using the IRQ stack, so revert to the original value in that case.
+ @
+ subs r2, sp, r0 @ SP above bottom of IRQ stack?
+ rsbscs r2, r2, #THREAD_SIZE @ ... and below the top?
+ movcs sp, r0
+
+ push {r0, lr} @ preserve LR and original SP
+
+ @ routine called with r0 = struct pt_regs *
+ bl generic_handle_arch_irq
+
+ pop {r0, lr}
+ mov sp, r0
+
@
@ Check for any pending work if returning to user
@
@@ -101,15 +110,17 @@ ENTRY(__switch_to)
str sp, [ip], #4
str lr, [ip], #4
mov r5, r0
+ mov r6, r2 @ Preserve 'next'
add r4, r2, #TI_CPU_SAVE
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
- mov ip, r4
mov r0, r5
- ldmia ip!, {r4 - r11} @ Load all regs saved previously
- ldr sp, [ip]
- ldr pc, [ip, #4]!
+ mov r1, r6
+ ldmia r4, {r4 - r12, lr} @ Load all regs saved previously
+ set_current r1, r2
+ mov sp, ip
+ bx lr
.fnend
ENDPROC(__switch_to)
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index a006585e1c09..83cc068586bc 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -22,12 +22,24 @@
#include <asm/ftrace.h>
#include <asm/insn.h>
#include <asm/set_memory.h>
+#include <asm/stacktrace.h>
#include <asm/patch.h>
+/*
+ * The compiler emitted profiling hook consists of
+ *
+ * PUSH {LR}
+ * BL __gnu_mcount_nc
+ *
+ * To turn this combined sequence into a NOP, we need to restore the value of
+ * SP before the PUSH. Let's use an ADD rather than a POP into LR, as LR is not
+ * modified anyway, and reloading LR from memory is highly likely to be less
+ * efficient.
+ */
#ifdef CONFIG_THUMB2_KERNEL
-#define NOP 0xf85deb04 /* pop.w {lr} */
+#define NOP 0xf10d0d04 /* add.w sp, sp, #4 */
#else
-#define NOP 0xe8bd4000 /* pop {lr} */
+#define NOP 0xe28dd004 /* add sp, sp, #4 */
#endif
#ifdef CONFIG_DYNAMIC_FTRACE
@@ -51,9 +63,20 @@ static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
return NOP;
}
-static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
+void ftrace_caller_from_init(void);
+void ftrace_regs_caller_from_init(void);
+
+static unsigned long __ref adjust_address(struct dyn_ftrace *rec,
+ unsigned long addr)
{
- return addr;
+ if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE) ||
+ system_state >= SYSTEM_FREEING_INITMEM ||
+ likely(!is_kernel_inittext(rec->ip)))
+ return addr;
+ if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) ||
+ addr == (unsigned long)&ftrace_caller)
+ return (unsigned long)&ftrace_caller_from_init;
+ return (unsigned long)&ftrace_regs_caller_from_init;
}
int ftrace_arch_code_modify_prepare(void)
@@ -189,15 +212,23 @@ int ftrace_make_nop(struct module *mod,
#endif
new = ftrace_nop_replace(rec);
- ret = ftrace_modify_code(ip, old, new, true);
+ /*
+ * Locations in .init.text may call __gnu_mcount_mc via a linker
+ * emitted veneer if they are too far away from its implementation, and
+ * so validation may fail spuriously in such cases. Let's work around
+ * this by omitting those from validation.
+ */
+ ret = ftrace_modify_code(ip, old, new, !is_kernel_inittext(ip));
return ret;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+asmlinkage
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
- unsigned long frame_pointer)
+ unsigned long frame_pointer,
+ unsigned long stack_pointer)
{
unsigned long return_hooker = (unsigned long) &return_to_handler;
unsigned long old;
@@ -205,6 +236,23 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
if (unlikely(atomic_read(&current->tracing_graph_pause)))
return;
+ if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) {
+ /* FP points one word below parent's top of stack */
+ frame_pointer += 4;
+ } else {
+ struct stackframe frame = {
+ .fp = frame_pointer,
+ .sp = stack_pointer,
+ .lr = self_addr,
+ .pc = self_addr,
+ };
+ if (unwind_frame(&frame) < 0)
+ return;
+ if (frame.lr != self_addr)
+ parent = frame.lr_addr;
+ frame_pointer = frame.sp;
+ }
+
old = *parent;
*parent = return_hooker;
@@ -225,7 +273,7 @@ static int __ftrace_modify_caller(unsigned long *callsite,
unsigned long caller_fn = (unsigned long) func;
unsigned long pc = (unsigned long) callsite;
unsigned long branch = arm_gen_branch(pc, caller_fn);
- unsigned long nop = 0xe1a00000; /* mov r0, r0 */
+ unsigned long nop = arm_gen_nop();
unsigned long old = enable ? nop : branch;
unsigned long new = enable ? branch : nop;
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index da18e0a17dc2..42cae73fcc19 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -105,10 +105,8 @@ __mmap_switched:
mov r1, #0
bl __memset @ clear .bss
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
adr_l r0, init_task @ get swapper task_struct
- set_current r0
-#endif
+ set_current r0, r1
ldmia r4, {r0, r1, r2, r3}
str r9, [r0] @ Save processor ID
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index c04dd94630c7..500612d3da2e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -424,6 +424,13 @@ ENDPROC(secondary_startup)
ENDPROC(secondary_startup_arm)
ENTRY(__secondary_switched)
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+ @ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+ @ as the ID map does not cover the vmalloc region.
+ mrc p15, 0, ip, c2, c0, 1 @ read TTBR1
+ mcr p15, 0, ip, c2, c0, 0 @ set TTBR0
+ instr_sync
+#endif
adr_l r7, secondary_data + 12 @ get secondary_data.stack
ldr sp, [r7]
ldr r0, [r7, #4] @ get secondary_data.task
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b79975bd988c..5c6f8d11a3ce 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -36,13 +36,53 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/cache-uniphier.h>
#include <asm/outercache.h>
+#include <asm/softirq_stack.h>
#include <asm/exception.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
+#include "reboot.h"
+
unsigned long irq_err_count;
+#ifdef CONFIG_IRQSTACKS
+
+asmlinkage DEFINE_PER_CPU_READ_MOSTLY(u8 *, irq_stack_ptr);
+
+static void __init init_irq_stacks(void)
+{
+ u8 *stack;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ if (!IS_ENABLED(CONFIG_VMAP_STACK))
+ stack = (u8 *)__get_free_pages(GFP_KERNEL,
+ THREAD_SIZE_ORDER);
+ else
+ stack = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN,
+ THREADINFO_GFP, NUMA_NO_NODE,
+ __builtin_return_address(0));
+
+ if (WARN_ON(!stack))
+ break;
+ per_cpu(irq_stack_ptr, cpu) = &stack[THREAD_SIZE];
+ }
+}
+
+static void ____do_softirq(void *arg)
+{
+ __do_softirq();
+}
+
+void do_softirq_own_stack(void)
+{
+ call_with_stack(____do_softirq, NULL,
+ __this_cpu_read(irq_stack_ptr));
+}
+
+#endif
+
int arch_show_interrupts(struct seq_file *p, int prec)
{
#ifdef CONFIG_FIQ
@@ -80,27 +120,14 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs)
ack_bad_irq(irq);
}
-/*
- * asm_do_IRQ is the interface to be used from assembly code.
- */
-asmlinkage void __exception_irq_entry
-asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
-{
- struct pt_regs *old_regs;
-
- irq_enter();
- old_regs = set_irq_regs(regs);
-
- handle_IRQ(irq, regs);
-
- set_irq_regs(old_regs);
- irq_exit();
-}
-
void __init init_IRQ(void)
{
int ret;
+#ifdef CONFIG_IRQSTACKS
+ init_irq_stacks();
+#endif
+
if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)
irqchip_init();
else
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index 7bd30c0a4280..22f937e6f3ff 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
return 0;
}
-static struct undef_hook kgdb_brkpt_hook = {
+static struct undef_hook kgdb_brkpt_arm_hook = {
.instr_mask = 0xffffffff,
.instr_val = KGDB_BREAKINST,
- .cpsr_mask = MODE_MASK,
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
.cpsr_val = SVC_MODE,
.fn = kgdb_brk_fn
};
-static struct undef_hook kgdb_compiled_brkpt_hook = {
+static struct undef_hook kgdb_brkpt_thumb_hook = {
+ .instr_mask = 0xffff,
+ .instr_val = KGDB_BREAKINST & 0xffff,
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
+ .cpsr_val = PSR_T_BIT | SVC_MODE,
+ .fn = kgdb_brk_fn
+};
+
+static struct undef_hook kgdb_compiled_brkpt_arm_hook = {
.instr_mask = 0xffffffff,
.instr_val = KGDB_COMPILED_BREAK,
- .cpsr_mask = MODE_MASK,
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
.cpsr_val = SVC_MODE,
.fn = kgdb_compiled_brk_fn
};
+static struct undef_hook kgdb_compiled_brkpt_thumb_hook = {
+ .instr_mask = 0xffff,
+ .instr_val = KGDB_COMPILED_BREAK & 0xffff,
+ .cpsr_mask = PSR_T_BIT | MODE_MASK,
+ .cpsr_val = PSR_T_BIT | SVC_MODE,
+ .fn = kgdb_compiled_brk_fn
+};
+
static int __kgdb_notify(struct die_args *args, unsigned long cmd)
{
struct pt_regs *regs = args->regs;
@@ -210,8 +226,10 @@ int kgdb_arch_init(void)
if (ret != 0)
return ret;
- register_undef_hook(&kgdb_brkpt_hook);
- register_undef_hook(&kgdb_compiled_brkpt_hook);
+ register_undef_hook(&kgdb_brkpt_arm_hook);
+ register_undef_hook(&kgdb_brkpt_thumb_hook);
+ register_undef_hook(&kgdb_compiled_brkpt_arm_hook);
+ register_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
return 0;
}
@@ -224,8 +242,10 @@ int kgdb_arch_init(void)
*/
void kgdb_arch_exit(void)
{
- unregister_undef_hook(&kgdb_brkpt_hook);
- unregister_undef_hook(&kgdb_compiled_brkpt_hook);
+ unregister_undef_hook(&kgdb_brkpt_arm_hook);
+ unregister_undef_hook(&kgdb_brkpt_thumb_hook);
+ unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook);
+ unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
unregister_die_notifier(&kgdb_notifier);
}
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index beac45e89ba6..549abcedf795 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -68,6 +68,44 @@ bool module_exit_section(const char *name)
strstarts(name, ".ARM.exidx.exit");
}
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+/*
+ * This implements the partitioning algorithm for group relocations as
+ * documented in the ARM AArch32 ELF psABI (IHI 0044).
+ *
+ * A single PC-relative symbol reference is divided in up to 3 add or subtract
+ * operations, where the final one could be incorporated into a load/store
+ * instruction with immediate offset. E.g.,
+ *
+ * ADD Rd, PC, #... or ADD Rd, PC, #...
+ * ADD Rd, Rd, #... ADD Rd, Rd, #...
+ * LDR Rd, [Rd, #...] ADD Rd, Rd, #...
+ *
+ * The latter has a guaranteed range of only 16 MiB (3x8 == 24 bits), so it is
+ * of limited use in the kernel. However, the ADD/ADD/LDR combo has a range of
+ * -/+ 256 MiB, (2x8 + 12 == 28 bits), which means it has sufficient range for
+ * any in-kernel symbol reference (unless module PLTs are being used).
+ *
+ * The main advantage of this approach over the typical pattern using a literal
+ * load is that literal loads may miss in the D-cache, and generally lead to
+ * lower cache efficiency for variables that are referenced often from many
+ * different places in the code.
+ */
+static u32 get_group_rem(u32 group, u32 *offset)
+{
+ u32 val = *offset;
+ u32 shift;
+ do {
+ shift = val ? (31 - __fls(val)) & ~1 : 32;
+ *offset = val;
+ if (!val)
+ break;
+ val &= 0xffffff >> shift;
+ } while (group--);
+ return shift;
+}
+#endif
+
int
apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
unsigned int relindex, struct module *module)
@@ -82,6 +120,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
unsigned long loc;
Elf32_Sym *sym;
const char *symname;
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+ u32 shift, group = 1;
+#endif
s32 offset;
u32 tmp;
#ifdef CONFIG_THUMB2_KERNEL
@@ -212,6 +253,55 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
*(u32 *)loc = __opcode_to_mem_arm(tmp);
break;
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+ case R_ARM_ALU_PC_G0_NC:
+ group = 0;
+ fallthrough;
+ case R_ARM_ALU_PC_G1_NC:
+ tmp = __mem_to_opcode_arm(*(u32 *)loc);
+ offset = ror32(tmp & 0xff, (tmp & 0xf00) >> 7);
+ if (tmp & BIT(22))
+ offset = -offset;
+ offset += sym->st_value - loc;
+ if (offset < 0) {
+ offset = -offset;
+ tmp = (tmp & ~BIT(23)) | BIT(22); // SUB opcode
+ } else {
+ tmp = (tmp & ~BIT(22)) | BIT(23); // ADD opcode
+ }
+
+ shift = get_group_rem(group, &offset);
+ if (shift < 24) {
+ offset >>= 24 - shift;
+ offset |= (shift + 8) << 7;
+ }
+ *(u32 *)loc = __opcode_to_mem_arm((tmp & ~0xfff) | offset);
+ break;
+
+ case R_ARM_LDR_PC_G2:
+ tmp = __mem_to_opcode_arm(*(u32 *)loc);
+ offset = tmp & 0xfff;
+ if (~tmp & BIT(23)) // U bit cleared?
+ offset = -offset;
+ offset += sym->st_value - loc;
+ if (offset < 0) {
+ offset = -offset;
+ tmp &= ~BIT(23); // clear U bit
+ } else {
+ tmp |= BIT(23); // set U bit
+ }
+ get_group_rem(2, &offset);
+
+ if (offset > 0xfff) {
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+ module->name, relindex, i, symname,
+ ELF32_R_TYPE(rel->r_info), loc,
+ sym->st_value);
+ return -ENOEXEC;
+ }
+ *(u32 *)loc = __opcode_to_mem_arm((tmp & ~0xfff) | offset);
+ break;
+#endif
#ifdef CONFIG_THUMB2_KERNEL
case R_ARM_THM_CALL:
case R_ARM_THM_JUMP24:
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index d47159f3791c..0617af11377f 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -36,7 +36,7 @@
#include "signal.h"
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
DEFINE_PER_CPU(struct task_struct *, __entry_task);
#endif
@@ -46,6 +46,11 @@ unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif
+#ifndef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+asmlinkage struct task_struct *__current;
+EXPORT_SYMBOL(__current);
+#endif
+
static const char *processor_modes[] __maybe_unused = {
"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
"UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index 00c11579406c..8aac1e10b117 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -41,7 +41,8 @@ void *return_address(unsigned int level)
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
- frame.pc = (unsigned long)return_address;
+here:
+ frame.pc = (unsigned long)&&here;
#ifdef CONFIG_KRETPROBES
frame.kr_cur = NULL;
frame.tsk = current;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 284a80c0b6e1..039feb7cd590 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -141,10 +141,10 @@ EXPORT_SYMBOL(outer_cache);
int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
struct stack {
- u32 irq[3];
- u32 abt[3];
- u32 und[3];
- u32 fiq[3];
+ u32 irq[4];
+ u32 abt[4];
+ u32 und[4];
+ u32 fiq[4];
} ____cacheline_aligned;
#ifndef CONFIG_CPU_V7M
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 43077e11dafd..a86a1d4f3461 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -67,6 +67,12 @@ ENTRY(__cpu_suspend)
ldr r4, =cpu_suspend_size
#endif
mov r5, sp @ current virtual SP
+#ifdef CONFIG_VMAP_STACK
+ @ Run the suspend code from the overflow stack so we don't have to rely
+ @ on vmalloc-to-phys conversions anywhere in the arch suspend code.
+ @ The original SP value captured in R5 will be restored on the way out.
+ ldr_this_cpu sp, overflow_stack_ptr, r6, r7
+#endif
add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn
sub sp, sp, r4 @ allocate CPU state on stack
ldr r3, =sleep_save_sp
@@ -113,6 +119,13 @@ ENTRY(cpu_resume_mmu)
ENDPROC(cpu_resume_mmu)
.popsection
cpu_resume_after_mmu:
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+ @ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+ @ as the ID map does not cover the vmalloc region.
+ mrc p15, 0, ip, c2, c0, 1 @ read TTBR1
+ mcr p15, 0, ip, c2, c0, 0 @ set TTBR0
+ instr_sync
+#endif
bl cpu_init @ restore the und/abt/irq banked regs
mov r0, #0 @ return zero on success
ldmfd sp!, {r4 - r11, pc}
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 97ee6b1567e9..73fc645fc4c7 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -400,6 +400,12 @@ static void smp_store_cpu_info(unsigned int cpuid)
check_cpu_icache_size(cpuid);
}
+static void set_current(struct task_struct *cur)
+{
+ /* Set TPIDRURO */
+ asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory");
+}
+
/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
@@ -628,11 +634,6 @@ static void ipi_complete(unsigned int cpu)
/*
* Main handler for inter-processor interrupts
*/
-asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
-{
- handle_IPI(ipinr, regs);
-}
-
static void do_handle_IPI(int ipinr)
{
unsigned int cpu = smp_processor_id();
diff --git a/arch/arm/kernel/spectre.c b/arch/arm/kernel/spectre.c
new file mode 100644
index 000000000000..0dcefc36fb7a
--- /dev/null
+++ b/arch/arm/kernel/spectre.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/bpf.h>
+#include <linux/cpu.h>
+#include <linux/device.h>
+
+#include <asm/spectre.h>
+
+static bool _unprivileged_ebpf_enabled(void)
+{
+#ifdef CONFIG_BPF_SYSCALL
+ return !sysctl_unprivileged_bpf_disabled;
+#else
+ return false;
+#endif
+}
+
+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "Mitigation: __user pointer sanitization\n");
+}
+
+static unsigned int spectre_v2_state;
+static unsigned int spectre_v2_methods;
+
+void spectre_v2_update_state(unsigned int state, unsigned int method)
+{
+ if (state > spectre_v2_state)
+ spectre_v2_state = state;
+ spectre_v2_methods |= method;
+}
+
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ const char *method;
+
+ if (spectre_v2_state == SPECTRE_UNAFFECTED)
+ return sprintf(buf, "%s\n", "Not affected");
+
+ if (spectre_v2_state != SPECTRE_MITIGATED)
+ return sprintf(buf, "%s\n", "Vulnerable");
+
+ if (_unprivileged_ebpf_enabled())
+ return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
+
+ switch (spectre_v2_methods) {
+ case SPECTRE_V2_METHOD_BPIALL:
+ method = "Branch predictor hardening";
+ break;
+
+ case SPECTRE_V2_METHOD_ICIALLU:
+ method = "I-cache invalidation";
+ break;
+
+ case SPECTRE_V2_METHOD_SMC:
+ case SPECTRE_V2_METHOD_HVC:
+ method = "Firmware call";
+ break;
+
+ case SPECTRE_V2_METHOD_LOOP8:
+ method = "History overwrite";
+ break;
+
+ default:
+ method = "Multiple mitigations";
+ break;
+ }
+
+ return sprintf(buf, "Mitigation: %s\n", method);
+}
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 75e905508f27..b5efecb3d730 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -160,7 +160,8 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
- frame.pc = (unsigned long)__save_stack_trace;
+here:
+ frame.pc = (unsigned long)&&here;
}
#ifdef CONFIG_KRETPROBES
frame.kr_cur = NULL;
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index 6166ba38bf99..b74bfcf94fb1 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -195,7 +195,7 @@ static int swp_handler(struct pt_regs *regs, unsigned int instr)
destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
/* Check access in reasonable access range for both SWP and SWPB */
- if (!access_ok((address & ~3), 4)) {
+ if (!access_ok((void __user *)(address & ~3), 4)) {
pr_debug("SWP{B} emulation: access to %p not allowed!\n",
(void *)address);
res = -EFAULT;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index da04ed85855a..9283dc65be31 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -30,11 +30,13 @@
#include <linux/atomic.h>
#include <asm/cacheflush.h>
#include <asm/exception.h>
+#include <asm/spectre.h>
#include <asm/unistd.h>
#include <asm/traps.h>
#include <asm/ptrace.h>
#include <asm/unwind.h>
#include <asm/tls.h>
+#include <asm/stacktrace.h>
#include <asm/system_misc.h>
#include <asm/opcodes.h>
@@ -60,13 +62,24 @@ static int __init user_debug_setup(char *str)
__setup("user_debug=", user_debug_setup);
#endif
-static void dump_mem(const char *, const char *, unsigned long, unsigned long);
-
void dump_backtrace_entry(unsigned long where, unsigned long from,
unsigned long frame, const char *loglvl)
{
unsigned long end = frame + 4 + sizeof(struct pt_regs);
+ if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER) &&
+ IS_ENABLED(CONFIG_CC_IS_GCC) &&
+ end > ALIGN(frame, THREAD_SIZE)) {
+ /*
+ * If we are walking past the end of the stack, it may be due
+ * to the fact that we are on an IRQ or overflow stack. In this
+ * case, we can load the address of the other stack from the
+ * frame record.
+ */
+ frame = ((unsigned long *)frame)[-2] - 4;
+ end = frame + 4 + sizeof(struct pt_regs);
+ }
+
#ifndef CONFIG_KALLSYMS
printk("%sFunction entered at [<%08lx>] from [<%08lx>]\n",
loglvl, where, from);
@@ -110,7 +123,8 @@ void dump_backtrace_stm(u32 *stack, u32 instruction, const char *loglvl)
static int verify_stack(unsigned long sp)
{
if (sp < PAGE_OFFSET ||
- (sp > (unsigned long)high_memory && high_memory != NULL))
+ (!IS_ENABLED(CONFIG_VMAP_STACK) &&
+ sp > (unsigned long)high_memory && high_memory != NULL))
return -EFAULT;
return 0;
@@ -120,8 +134,8 @@ static int verify_stack(unsigned long sp)
/*
* Dump out the contents of some memory nicely...
*/
-static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
- unsigned long top)
+void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+ unsigned long top)
{
unsigned long first;
int i;
@@ -280,7 +294,8 @@ static int __die(const char *str, int err, struct pt_regs *regs)
if (!user_mode(regs) || in_interrupt()) {
dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
- THREAD_SIZE + (unsigned long)task_stack_page(tsk));
+ ALIGN(regs->ARM_sp - THREAD_SIZE, THREAD_ALIGN)
+ + THREAD_SIZE);
dump_backtrace(regs, tsk, KERN_EMERG);
dump_instr(KERN_EMERG, regs);
}
@@ -576,7 +591,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
if (end < start || flags)
return -EINVAL;
- if (!access_ok(start, end - start))
+ if (!access_ok((void __user *)start, end - start))
return -EFAULT;
return __do_cache_op(start, end);
@@ -789,10 +804,59 @@ static inline void __init kuser_init(void *vectors)
}
#endif
+#ifndef CONFIG_CPU_V7M
+static void copy_from_lma(void *vma, void *lma_start, void *lma_end)
+{
+ memcpy(vma, lma_start, lma_end - lma_start);
+}
+
+static void flush_vectors(void *vma, size_t offset, size_t size)
+{
+ unsigned long start = (unsigned long)vma + offset;
+ unsigned long end = start + size;
+
+ flush_icache_range(start, end);
+}
+
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+int spectre_bhb_update_vectors(unsigned int method)
+{
+ extern char __vectors_bhb_bpiall_start[], __vectors_bhb_bpiall_end[];
+ extern char __vectors_bhb_loop8_start[], __vectors_bhb_loop8_end[];
+ void *vec_start, *vec_end;
+
+ if (system_state >= SYSTEM_FREEING_INITMEM) {
+ pr_err("CPU%u: Spectre BHB workaround too late - system vulnerable\n",
+ smp_processor_id());
+ return SPECTRE_VULNERABLE;
+ }
+
+ switch (method) {
+ case SPECTRE_V2_METHOD_LOOP8:
+ vec_start = __vectors_bhb_loop8_start;
+ vec_end = __vectors_bhb_loop8_end;
+ break;
+
+ case SPECTRE_V2_METHOD_BPIALL:
+ vec_start = __vectors_bhb_bpiall_start;
+ vec_end = __vectors_bhb_bpiall_end;
+ break;
+
+ default:
+ pr_err("CPU%u: unknown Spectre BHB state %d\n",
+ smp_processor_id(), method);
+ return SPECTRE_VULNERABLE;
+ }
+
+ copy_from_lma(vectors_page, vec_start, vec_end);
+ flush_vectors(vectors_page, 0, vec_end - vec_start);
+
+ return SPECTRE_MITIGATED;
+}
+#endif
+
void __init early_trap_init(void *vectors_base)
{
-#ifndef CONFIG_CPU_V7M
- unsigned long vectors = (unsigned long)vectors_base;
extern char __stubs_start[], __stubs_end[];
extern char __vectors_start[], __vectors_end[];
unsigned i;
@@ -813,17 +877,87 @@ void __init early_trap_init(void *vectors_base)
* into the vector page, mapped at 0xffff0000, and ensure these
* are visible to the instruction stream.
*/
- memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
- memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
+ copy_from_lma(vectors_base, __vectors_start, __vectors_end);
+ copy_from_lma(vectors_base + 0x1000, __stubs_start, __stubs_end);
kuser_init(vectors_base);
- flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
+ flush_vectors(vectors_base, 0, PAGE_SIZE * 2);
+}
#else /* ifndef CONFIG_CPU_V7M */
+void __init early_trap_init(void *vectors_base)
+{
/*
* on V7-M there is no need to copy the vector table to a dedicated
* memory area. The address is configurable and so a table in the kernel
* image can be used.
*/
+}
+#endif
+
+#ifdef CONFIG_VMAP_STACK
+
+DECLARE_PER_CPU(u8 *, irq_stack_ptr);
+
+asmlinkage DEFINE_PER_CPU(u8 *, overflow_stack_ptr);
+
+static int __init allocate_overflow_stacks(void)
+{
+ u8 *stack;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ stack = (u8 *)__get_free_page(GFP_KERNEL);
+ if (WARN_ON(!stack))
+ return -ENOMEM;
+ per_cpu(overflow_stack_ptr, cpu) = &stack[OVERFLOW_STACK_SIZE];
+ }
+ return 0;
+}
+early_initcall(allocate_overflow_stacks);
+
+asmlinkage void handle_bad_stack(struct pt_regs *regs)
+{
+ unsigned long tsk_stk = (unsigned long)current->stack;
+#ifdef CONFIG_IRQSTACKS
+ unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr);
#endif
+ unsigned long ovf_stk = (unsigned long)this_cpu_read(overflow_stack_ptr);
+
+ console_verbose();
+ pr_emerg("Insufficient stack space to handle exception!");
+
+ pr_emerg("Task stack: [0x%08lx..0x%08lx]\n",
+ tsk_stk, tsk_stk + THREAD_SIZE);
+#ifdef CONFIG_IRQSTACKS
+ pr_emerg("IRQ stack: [0x%08lx..0x%08lx]\n",
+ irq_stk - THREAD_SIZE, irq_stk);
+#endif
+ pr_emerg("Overflow stack: [0x%08lx..0x%08lx]\n",
+ ovf_stk - OVERFLOW_STACK_SIZE, ovf_stk);
+
+ die("kernel stack overflow", regs, 0);
+}
+
+#ifndef CONFIG_ARM_LPAE
+/*
+ * Normally, we rely on the logic in do_translation_fault() to update stale PMD
+ * entries covering the vmalloc space in a task's page tables when it first
+ * accesses the region in question. Unfortunately, this is not sufficient when
+ * the task stack resides in the vmalloc region, as do_translation_fault() is a
+ * C function that needs a stack to run.
+ *
+ * So we need to ensure that these PMD entries are up to date *before* the MM
+ * switch. As we already have some logic in the MM switch path that takes care
+ * of this, let's trigger it by bumping the counter every time the core vmalloc
+ * code modifies a PMD entry in the vmalloc region. Use release semantics on
+ * the store so that other CPUs observing the counter's new value are
+ * guaranteed to see the updated page table entries as well.
+ */
+void arch_sync_kernel_mappings(unsigned long start, unsigned long end)
+{
+ if (start < VMALLOC_END && end > VMALLOC_START)
+ atomic_inc_return_release(&init_mm.context.vmalloc_seq);
}
+#endif
+#endif
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 59fdf257bf8b..a37ea6c772cd 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -33,6 +33,8 @@
#include <asm/traps.h>
#include <asm/unwind.h>
+#include "reboot.h"
+
/* Dummy functions to avoid linker complaints */
void __aeabi_unwind_cpp_pr0(void)
{
@@ -53,6 +55,7 @@ struct unwind_ctrl_block {
unsigned long vrs[16]; /* virtual register set */
const unsigned long *insn; /* pointer to the current instructions word */
unsigned long sp_high; /* highest value of sp allowed */
+ unsigned long *lr_addr; /* address of LR value on the stack */
/*
* 1 : check for stack overflow for each register pop.
* 0 : save overhead if there is plenty of stack remaining.
@@ -237,6 +240,8 @@ static int unwind_pop_register(struct unwind_ctrl_block *ctrl,
* from being tracked by KASAN.
*/
ctrl->vrs[reg] = READ_ONCE_NOCHECK(*(*vsp));
+ if (reg == 14)
+ ctrl->lr_addr = *vsp;
(*vsp)++;
return URC_OK;
}
@@ -256,8 +261,9 @@ static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl,
mask >>= 1;
reg++;
}
- if (!load_sp)
+ if (!load_sp) {
ctrl->vrs[SP] = (unsigned long)vsp;
+ }
return URC_OK;
}
@@ -313,9 +319,9 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
if ((insn & 0xc0) == 0x00)
ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
- else if ((insn & 0xc0) == 0x40)
+ else if ((insn & 0xc0) == 0x40) {
ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
- else if ((insn & 0xf0) == 0x80) {
+ } else if ((insn & 0xf0) == 0x80) {
unsigned long mask;
insn = (insn << 8) | unwind_get_byte(ctrl);
@@ -330,9 +336,9 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
if (ret)
goto error;
} else if ((insn & 0xf0) == 0x90 &&
- (insn & 0x0d) != 0x0d)
+ (insn & 0x0d) != 0x0d) {
ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
- else if ((insn & 0xf0) == 0xa0) {
+ } else if ((insn & 0xf0) == 0xa0) {
ret = unwind_exec_pop_r4_to_rN(ctrl, insn);
if (ret)
goto error;
@@ -375,23 +381,22 @@ error:
*/
int unwind_frame(struct stackframe *frame)
{
- unsigned long low;
const struct unwind_idx *idx;
struct unwind_ctrl_block ctrl;
+ unsigned long sp_low;
/* store the highest address on the stack to avoid crossing it*/
- low = frame->sp;
- ctrl.sp_high = ALIGN(low, THREAD_SIZE);
+ sp_low = frame->sp;
+ ctrl.sp_high = ALIGN(sp_low - THREAD_SIZE, THREAD_ALIGN)
+ + THREAD_SIZE;
pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
frame->pc, frame->lr, frame->sp);
- if (!kernel_text_address(frame->pc))
- return -URC_FAILURE;
-
idx = unwind_find_idx(frame->pc);
if (!idx) {
- pr_warn("unwind: Index not found %08lx\n", frame->pc);
+ if (frame->pc && kernel_text_address(frame->pc))
+ pr_warn("unwind: Index not found %08lx\n", frame->pc);
return -URC_FAILURE;
}
@@ -403,7 +408,20 @@ int unwind_frame(struct stackframe *frame)
if (idx->insn == 1)
/* can't unwind */
return -URC_FAILURE;
- else if ((idx->insn & 0x80000000) == 0)
+ else if (frame->pc == prel31_to_addr(&idx->addr_offset)) {
+ /*
+ * Unwinding is tricky when we're halfway through the prologue,
+ * since the stack frame that the unwinder expects may not be
+ * fully set up yet. However, one thing we do know for sure is
+ * that if we are unwinding from the very first instruction of
+ * a function, we are still effectively in the stack frame of
+ * the caller, and the unwind info has no relevance yet.
+ */
+ if (frame->pc == frame->lr)
+ return -URC_FAILURE;
+ frame->pc = frame->lr;
+ return URC_OK;
+ } else if ((idx->insn & 0x80000000) == 0)
/* prel31 to the unwind table */
ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
else if ((idx->insn & 0xff000000) == 0x80000000)
@@ -430,6 +448,16 @@ int unwind_frame(struct stackframe *frame)
ctrl.check_each_pop = 0;
+ if (prel31_to_addr(&idx->addr_offset) == (u32)&call_with_stack) {
+ /*
+ * call_with_stack() is the only place where we permit SP to
+ * jump from one stack to another, and since we know it is
+ * guaranteed to happen, set up the SP bounds accordingly.
+ */
+ sp_low = frame->fp;
+ ctrl.sp_high = ALIGN(frame->fp, THREAD_SIZE);
+ }
+
while (ctrl.entries > 0) {
int urc;
if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs))
@@ -437,7 +465,7 @@ int unwind_frame(struct stackframe *frame)
urc = unwind_exec_insn(&ctrl);
if (urc < 0)
return urc;
- if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.sp_high)
+ if (ctrl.vrs[SP] < sp_low || ctrl.vrs[SP] > ctrl.sp_high)
return -URC_FAILURE;
}
@@ -452,6 +480,7 @@ int unwind_frame(struct stackframe *frame)
frame->sp = ctrl.vrs[SP];
frame->lr = ctrl.vrs[LR];
frame->pc = ctrl.vrs[PC];
+ frame->lr_addr = ctrl.lr_addr;
return URC_OK;
}
@@ -475,7 +504,12 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk,
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
- frame.pc = (unsigned long)unwind_backtrace;
+ /* We are saving the stack and execution state at this
+ * point, so we should ensure that frame.pc is within
+ * this block of code.
+ */
+here:
+ frame.pc = (unsigned long)&&here;
} else {
/* task blocked in __switch_to */
frame.fp = thread_saved_fp(tsk);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index f02d617e3359..aa12b65a7fd6 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -138,12 +138,12 @@ SECTIONS
#ifdef CONFIG_STRICT_KERNEL_RWX
. = ALIGN(1<<SECTION_SHIFT);
#else
- . = ALIGN(THREAD_SIZE);
+ . = ALIGN(THREAD_ALIGN);
#endif
__init_end = .;
_sdata = .;
- RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+ RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
_edata = .;
BSS_SECTION(0, 0, 0)
diff --git a/arch/arm/lib/backtrace-clang.S b/arch/arm/lib/backtrace-clang.S
index 5b2cdb1003e3..290c52a60fc6 100644
--- a/arch/arm/lib/backtrace-clang.S
+++ b/arch/arm/lib/backtrace-clang.S
@@ -144,7 +144,7 @@ for_each_frame: tst frame, mask @ Check for address exceptions
*/
1003: ldr sv_lr, [sv_fp, #4] @ get saved lr from next frame
- ldr r0, [sv_lr, #-4] @ get call instruction
+1004: ldr r0, [sv_lr, #-4] @ get call instruction
ldr r3, .Lopcode+4
and r2, r3, r0 @ is this a bl call
teq r2, r3
@@ -164,7 +164,7 @@ finished_setup:
/*
* Print the function (sv_pc) and where it was called from (sv_lr).
*/
-1004: mov r0, sv_pc
+ mov r0, sv_pc
mov r1, sv_lr
mov r2, frame
@@ -197,6 +197,14 @@ finished_setup:
cmp sv_fp, frame @ next frame must be
mov frame, sv_fp @ above the current frame
+#ifdef CONFIG_IRQSTACKS
+ @
+ @ Kernel stacks may be discontiguous in memory. If the next
+ @ frame is below the previous frame, accept it as long as it
+ @ lives in kernel memory.
+ @
+ cmpls sv_fp, #PAGE_OFFSET
+#endif
bhi for_each_frame
1006: adr r0, .Lbad
@@ -210,7 +218,7 @@ ENDPROC(c_backtrace)
.long 1001b, 1006b
.long 1002b, 1006b
.long 1003b, 1006b
- .long 1004b, 1006b
+ .long 1004b, finished_setup
.long 1005b, 1006b
.popsection
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index e8408f22d4dc..293a2716bd20 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -98,6 +98,14 @@ for_each_frame: tst frame, mask @ Check for address exceptions
cmp sv_fp, frame @ next frame must be
mov frame, sv_fp @ above the current frame
+#ifdef CONFIG_IRQSTACKS
+ @
+ @ Kernel stacks may be discontiguous in memory. If the next
+ @ frame is below the previous frame, accept it as long as it
+ @ lives in kernel memory.
+ @
+ cmpls sv_fp, #PAGE_OFFSET
+#endif
bhi for_each_frame
1006: adr r0, .Lbad
diff --git a/arch/arm/lib/call_with_stack.S b/arch/arm/lib/call_with_stack.S
index 28b0341ae786..0a268a6c513c 100644
--- a/arch/arm/lib/call_with_stack.S
+++ b/arch/arm/lib/call_with_stack.S
@@ -8,25 +8,42 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/unwind.h>
/*
* void call_with_stack(void (*fn)(void *), void *arg, void *sp)
*
* Change the stack to that pointed at by sp, then invoke fn(arg) with
* the new stack.
+ *
+ * The sequence below follows the APCS frame convention for frame pointer
+ * unwinding, and implements the unwinder annotations needed by the EABI
+ * unwinder.
*/
-ENTRY(call_with_stack)
- str sp, [r2, #-4]!
- str lr, [r2, #-4]!
+ENTRY(call_with_stack)
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+ mov ip, sp
+ push {fp, ip, lr, pc}
+ sub fp, ip, #4
+#else
+UNWIND( .fnstart )
+UNWIND( .save {fpreg, lr} )
+ push {fpreg, lr}
+UNWIND( .setfp fpreg, sp )
+ mov fpreg, sp
+#endif
mov sp, r2
mov r2, r0
mov r0, r1
- badr lr, 1f
- ret r2
+ bl_r r2
-1: ldr lr, [sp]
- ldr sp, [sp, #4]
- ret lr
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+ ldmdb fp, {fp, sp, pc}
+#else
+ mov sp, fpreg
+ pop {fpreg, pc}
+UNWIND( .fnend )
+#endif
ENDPROC(call_with_stack)
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 480a20766137..270de7debd0f 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -91,18 +91,15 @@
strb\cond \reg, [\ptr], #1
.endm
- .macro enter reg1 reg2
+ .macro enter regs:vararg
mov r3, #0
- stmdb sp!, {r0, r2, r3, \reg1, \reg2}
+UNWIND( .save {r0, r2, r3, \regs} )
+ stmdb sp!, {r0, r2, r3, \regs}
.endm
- .macro usave reg1 reg2
- UNWIND( .save {r0, r2, r3, \reg1, \reg2} )
- .endm
-
- .macro exit reg1 reg2
+ .macro exit regs:vararg
add sp, sp, #8
- ldmfd sp!, {r0, \reg1, \reg2}
+ ldmfd sp!, {r0, \regs}
.endm
.text
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 810a805d36dc..8fbafb074fe9 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -69,13 +69,10 @@
* than one 32bit instruction in Thumb-2)
*/
-
- UNWIND( .fnstart )
- enter r4, lr
- UNWIND( .fnend )
-
UNWIND( .fnstart )
- usave r4, lr @ in first stmdb block
+ enter r4, UNWIND(fpreg,) lr
+ UNWIND( .setfp fpreg, sp )
+ UNWIND( mov fpreg, sp )
subs r2, r2, #4
blt 8f
@@ -86,12 +83,7 @@
bne 10f
1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
- UNWIND( .fnend )
-
- UNWIND( .fnstart )
- usave r4, lr
- UNWIND( .save {r5 - r8} ) @ in second stmfd block
+ stmfd sp!, {r5, r6, r8, r9}
blt 5f
CALGN( ands ip, r0, #31 )
@@ -110,9 +102,9 @@
PLD( pld [r1, #92] )
3: PLD( pld [r1, #124] )
-4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+4: ldr8w r1, r3, r4, r5, r6, r8, r9, ip, lr, abort=20f
subs r2, r2, #32
- str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ str8w r0, r3, r4, r5, r6, r8, r9, ip, lr, abort=20f
bge 3b
PLD( cmn r2, #96 )
PLD( bge 4b )
@@ -132,8 +124,8 @@
ldr1w r1, r4, abort=20f
ldr1w r1, r5, abort=20f
ldr1w r1, r6, abort=20f
- ldr1w r1, r7, abort=20f
ldr1w r1, r8, abort=20f
+ ldr1w r1, r9, abort=20f
ldr1w r1, lr, abort=20f
#if LDR1W_SHIFT < STR1W_SHIFT
@@ -150,17 +142,14 @@
str1w r0, r4, abort=20f
str1w r0, r5, abort=20f
str1w r0, r6, abort=20f
- str1w r0, r7, abort=20f
str1w r0, r8, abort=20f
+ str1w r0, r9, abort=20f
str1w r0, lr, abort=20f
CALGN( bcs 2b )
-7: ldmfd sp!, {r5 - r8}
- UNWIND( .fnend ) @ end of second stmfd block
+7: ldmfd sp!, {r5, r6, r8, r9}
- UNWIND( .fnstart )
- usave r4, lr @ still in first stmdb block
8: movs r2, r2, lsl #31
ldr1b r1, r3, ne, abort=21f
ldr1b r1, r4, cs, abort=21f
@@ -169,7 +158,7 @@
str1b r0, r4, cs, abort=21f
str1b r0, ip, cs, abort=21f
- exit r4, pc
+ exit r4, UNWIND(fpreg,) pc
9: rsb ip, ip, #4
cmp ip, #2
@@ -189,13 +178,10 @@
ldr1w r1, lr, abort=21f
beq 17f
bgt 18f
- UNWIND( .fnend )
.macro forward_copy_shift pull push
- UNWIND( .fnstart )
- usave r4, lr @ still in first stmdb block
subs r2, r2, #28
blt 14f
@@ -205,12 +191,8 @@
CALGN( subcc r2, r2, ip )
CALGN( bcc 15f )
-11: stmfd sp!, {r5 - r9}
- UNWIND( .fnend )
+11: stmfd sp!, {r5, r6, r8 - r10}
- UNWIND( .fnstart )
- usave r4, lr
- UNWIND( .save {r5 - r9} ) @ in new second stmfd block
PLD( pld [r1, #0] )
PLD( subs r2, r2, #96 )
PLD( pld [r1, #28] )
@@ -219,35 +201,32 @@
PLD( pld [r1, #92] )
12: PLD( pld [r1, #124] )
-13: ldr4w r1, r4, r5, r6, r7, abort=19f
+13: ldr4w r1, r4, r5, r6, r8, abort=19f
mov r3, lr, lspull #\pull
subs r2, r2, #32
- ldr4w r1, r8, r9, ip, lr, abort=19f
+ ldr4w r1, r9, r10, ip, lr, abort=19f
orr r3, r3, r4, lspush #\push
mov r4, r4, lspull #\pull
orr r4, r4, r5, lspush #\push
mov r5, r5, lspull #\pull
orr r5, r5, r6, lspush #\push
mov r6, r6, lspull #\pull
- orr r6, r6, r7, lspush #\push
- mov r7, r7, lspull #\pull
- orr r7, r7, r8, lspush #\push
+ orr r6, r6, r8, lspush #\push
mov r8, r8, lspull #\pull
orr r8, r8, r9, lspush #\push
mov r9, r9, lspull #\pull
- orr r9, r9, ip, lspush #\push
+ orr r9, r9, r10, lspush #\push
+ mov r10, r10, lspull #\pull
+ orr r10, r10, ip, lspush #\push
mov ip, ip, lspull #\pull
orr ip, ip, lr, lspush #\push
- str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, abort=19f
+ str8w r0, r3, r4, r5, r6, r8, r9, r10, ip, abort=19f
bge 12b
PLD( cmn r2, #96 )
PLD( bge 13b )
- ldmfd sp!, {r5 - r9}
- UNWIND( .fnend ) @ end of the second stmfd block
+ ldmfd sp!, {r5, r6, r8 - r10}
- UNWIND( .fnstart )
- usave r4, lr @ still in first stmdb block
14: ands ip, r2, #28
beq 16f
@@ -262,7 +241,6 @@
16: sub r1, r1, #(\push / 8)
b 8b
- UNWIND( .fnend )
.endm
@@ -273,6 +251,7 @@
18: forward_copy_shift pull=24 push=8
+ UNWIND( .fnend )
/*
* Abort preamble and completion macros.
@@ -282,13 +261,13 @@
*/
.macro copy_abort_preamble
-19: ldmfd sp!, {r5 - r9}
+19: ldmfd sp!, {r5, r6, r8 - r10}
b 21f
-20: ldmfd sp!, {r5 - r8}
+20: ldmfd sp!, {r5, r6, r8, r9}
21:
.endm
.macro copy_abort_end
- ldmfd sp!, {r4, pc}
+ ldmfd sp!, {r4, UNWIND(fpreg,) pc}
.endm
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 842ea5ede485..fac49e57cc0b 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -90,18 +90,15 @@
strusr \reg, \ptr, 1, \cond, abort=\abort
.endm
- .macro enter reg1 reg2
+ .macro enter regs:vararg
mov r3, #0
- stmdb sp!, {r0, r2, r3, \reg1, \reg2}
+UNWIND( .save {r0, r2, r3, \regs} )
+ stmdb sp!, {r0, r2, r3, \regs}
.endm
- .macro usave reg1 reg2
- UNWIND( .save {r0, r2, r3, \reg1, \reg2} )
- .endm
-
- .macro exit reg1 reg2
+ .macro exit regs:vararg
add sp, sp, #8
- ldmfd sp!, {r0, \reg1, \reg2}
+ ldmfd sp!, {r0, \regs}
.endm
.text
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index e4caf48c089f..90f2b645aa0d 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -42,16 +42,13 @@
strb\cond \reg, [\ptr], #1
.endm
- .macro enter reg1 reg2
- stmdb sp!, {r0, \reg1, \reg2}
+ .macro enter regs:vararg
+UNWIND( .save {r0, \regs} )
+ stmdb sp!, {r0, \regs}
.endm
- .macro usave reg1 reg2
- UNWIND( .save {r0, \reg1, \reg2} )
- .endm
-
- .macro exit reg1 reg2
- ldmfd sp!, {r0, \reg1, \reg2}
+ .macro exit regs:vararg
+ ldmfd sp!, {r0, \regs}
.endm
.text
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index 6fecc12a1f51..6410554039fd 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -31,12 +31,13 @@ WEAK(memmove)
subs ip, r0, r1
cmphi r2, ip
bls __memcpy
-
- stmfd sp!, {r0, r4, lr}
UNWIND( .fnend )
UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} ) @ in first stmfd block
+ UNWIND( .save {r0, r4, fpreg, lr} )
+ stmfd sp!, {r0, r4, UNWIND(fpreg,) lr}
+ UNWIND( .setfp fpreg, sp )
+ UNWIND( mov fpreg, sp )
add r1, r1, r2
add r0, r0, r2
subs r2, r2, #4
@@ -48,12 +49,7 @@ WEAK(memmove)
bne 10f
1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
- UNWIND( .fnend )
-
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} )
- UNWIND( .save {r5 - r8} ) @ in second stmfd block
+ stmfd sp!, {r5, r6, r8, r9}
blt 5f
CALGN( ands ip, r0, #31 )
@@ -72,9 +68,9 @@ WEAK(memmove)
PLD( pld [r1, #-96] )
3: PLD( pld [r1, #-128] )
-4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+4: ldmdb r1!, {r3, r4, r5, r6, r8, r9, ip, lr}
subs r2, r2, #32
- stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ stmdb r0!, {r3, r4, r5, r6, r8, r9, ip, lr}
bge 3b
PLD( cmn r2, #96 )
PLD( bge 4b )
@@ -88,8 +84,8 @@ WEAK(memmove)
W(ldr) r4, [r1, #-4]!
W(ldr) r5, [r1, #-4]!
W(ldr) r6, [r1, #-4]!
- W(ldr) r7, [r1, #-4]!
W(ldr) r8, [r1, #-4]!
+ W(ldr) r9, [r1, #-4]!
W(ldr) lr, [r1, #-4]!
add pc, pc, ip
@@ -99,17 +95,13 @@ WEAK(memmove)
W(str) r4, [r0, #-4]!
W(str) r5, [r0, #-4]!
W(str) r6, [r0, #-4]!
- W(str) r7, [r0, #-4]!
W(str) r8, [r0, #-4]!
+ W(str) r9, [r0, #-4]!
W(str) lr, [r0, #-4]!
CALGN( bcs 2b )
-7: ldmfd sp!, {r5 - r8}
- UNWIND( .fnend ) @ end of second stmfd block
-
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
+7: ldmfd sp!, {r5, r6, r8, r9}
8: movs r2, r2, lsl #31
ldrbne r3, [r1, #-1]!
@@ -118,7 +110,7 @@ WEAK(memmove)
strbne r3, [r0, #-1]!
strbcs r4, [r0, #-1]!
strbcs ip, [r0, #-1]
- ldmfd sp!, {r0, r4, pc}
+ ldmfd sp!, {r0, r4, UNWIND(fpreg,) pc}
9: cmp ip, #2
ldrbgt r3, [r1, #-1]!
@@ -137,13 +129,10 @@ WEAK(memmove)
ldr r3, [r1, #0]
beq 17f
blt 18f
- UNWIND( .fnend )
.macro backward_copy_shift push pull
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
subs r2, r2, #28
blt 14f
@@ -152,12 +141,7 @@ WEAK(memmove)
CALGN( subcc r2, r2, ip )
CALGN( bcc 15f )
-11: stmfd sp!, {r5 - r9}
- UNWIND( .fnend )
-
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} )
- UNWIND( .save {r5 - r9} ) @ in new second stmfd block
+11: stmfd sp!, {r5, r6, r8 - r10}
PLD( pld [r1, #-4] )
PLD( subs r2, r2, #96 )
@@ -167,35 +151,31 @@ WEAK(memmove)
PLD( pld [r1, #-96] )
12: PLD( pld [r1, #-128] )
-13: ldmdb r1!, {r7, r8, r9, ip}
+13: ldmdb r1!, {r8, r9, r10, ip}
mov lr, r3, lspush #\push
subs r2, r2, #32
ldmdb r1!, {r3, r4, r5, r6}
orr lr, lr, ip, lspull #\pull
mov ip, ip, lspush #\push
- orr ip, ip, r9, lspull #\pull
+ orr ip, ip, r10, lspull #\pull
+ mov r10, r10, lspush #\push
+ orr r10, r10, r9, lspull #\pull
mov r9, r9, lspush #\push
orr r9, r9, r8, lspull #\pull
mov r8, r8, lspush #\push
- orr r8, r8, r7, lspull #\pull
- mov r7, r7, lspush #\push
- orr r7, r7, r6, lspull #\pull
+ orr r8, r8, r6, lspull #\pull
mov r6, r6, lspush #\push
orr r6, r6, r5, lspull #\pull
mov r5, r5, lspush #\push
orr r5, r5, r4, lspull #\pull
mov r4, r4, lspush #\push
orr r4, r4, r3, lspull #\pull
- stmdb r0!, {r4 - r9, ip, lr}
+ stmdb r0!, {r4 - r6, r8 - r10, ip, lr}
bge 12b
PLD( cmn r2, #96 )
PLD( bge 13b )
- ldmfd sp!, {r5 - r9}
- UNWIND( .fnend ) @ end of the second stmfd block
-
- UNWIND( .fnstart )
- UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
+ ldmfd sp!, {r5, r6, r8 - r10}
14: ands ip, r2, #28
beq 16f
@@ -211,7 +191,6 @@ WEAK(memmove)
16: add r1, r1, #(\pull / 8)
b 8b
- UNWIND( .fnend )
.endm
@@ -222,5 +201,6 @@ WEAK(memmove)
18: backward_copy_shift push=24 pull=8
+ UNWIND( .fnend )
ENDPROC(memmove)
ENDPROC(__memmove)
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
index 9817cb258c1a..d71ab61430b2 100644
--- a/arch/arm/lib/memset.S
+++ b/arch/arm/lib/memset.S
@@ -28,16 +28,16 @@ UNWIND( .fnstart )
mov r3, r1
7: cmp r2, #16
blt 4f
+UNWIND( .fnend )
#if ! CALGN(1)+0
/*
* We need 2 extra registers for this loop - use r8 and the LR
*/
- stmfd sp!, {r8, lr}
-UNWIND( .fnend )
UNWIND( .fnstart )
UNWIND( .save {r8, lr} )
+ stmfd sp!, {r8, lr}
mov r8, r1
mov lr, r3
@@ -66,10 +66,9 @@ UNWIND( .fnend )
* whole cache lines at once.
*/
- stmfd sp!, {r4-r8, lr}
-UNWIND( .fnend )
UNWIND( .fnstart )
UNWIND( .save {r4-r8, lr} )
+ stmfd sp!, {r4-r8, lr}
mov r4, r1
mov r5, r3
mov r6, r1
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index 106f83a5ea6d..c30b689bec2e 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -92,11 +92,6 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
unsigned long ua_flags;
int atomic;
- if (uaccess_kernel()) {
- memcpy((void *)to, from, n);
- return 0;
- }
-
/* the mmap semaphore is taken only if not in an atomic context */
atomic = faulthandler_disabled();
@@ -165,11 +160,6 @@ __clear_user_memset(void __user *addr, unsigned long n)
{
unsigned long ua_flags;
- if (uaccess_kernel()) {
- memset((void *)addr, 0, n);
- return 0;
- }
-
mmap_read_lock(current->mm);
while (n) {
pte_t *pte;
diff --git a/arch/arm/lib/xor-neon.c b/arch/arm/lib/xor-neon.c
index b99dd8e1c93f..522510baed49 100644
--- a/arch/arm/lib/xor-neon.c
+++ b/arch/arm/lib/xor-neon.c
@@ -17,17 +17,11 @@ MODULE_LICENSE("GPL");
/*
* Pull in the reference implementations while instructing GCC (through
* -ftree-vectorize) to attempt to exploit implicit parallelism and emit
- * NEON instructions.
+ * NEON instructions. Clang does this by default at O2 so no pragma is
+ * needed.
*/
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#ifdef CONFIG_CC_IS_GCC
#pragma GCC optimize "tree-vectorize"
-#else
-/*
- * While older versions of GCC do not generate incorrect code, they fail to
- * recognize the parallel nature of these functions, and emit plain ARM code,
- * which is known to be slower than the optimized ARM code in asm-arm/xor.h.
- */
-#warning This code requires at least version 4.6 of GCC
#endif
#pragma GCC diagnostic ignored "-Wunused-variable"
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 02f6b108fd5d..279810381256 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -63,6 +63,7 @@ config SOC_SAMA7G5
select HAVE_AT91_GENERATED_CLK
select HAVE_AT91_SAM9X60_PLL
select HAVE_AT91_UTMI
+ select PM_OPP
select SOC_SAMA7
help
Select this if you are using one of Microchip's SAMA7G5 family SoC.
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index dd6f4ce3f766..0fd609e26615 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -605,6 +605,30 @@ static void at91sam9_sdram_standby(void)
at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
}
+static void sama7g5_standby(void)
+{
+ int pwrtmg, ratio;
+
+ pwrtmg = readl(soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+ ratio = readl(soc_pm.data.pmc + AT91_PMC_RATIO);
+
+ /*
+ * Place RAM into self-refresh after a maximum idle clocks. The maximum
+ * idle clocks is configured by bootloader in
+ * UDDRC_PWRMGT.SELFREF_TO_X32.
+ */
+ writel(pwrtmg | UDDRC_PWRCTL_SELFREF_EN,
+ soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+ /* Divide CPU clock by 16. */
+ writel(ratio & ~AT91_PMC_RATIO_RATIO, soc_pm.data.pmc + AT91_PMC_RATIO);
+
+ cpu_do_idle();
+
+ /* Restore previous configuration. */
+ writel(ratio, soc_pm.data.pmc + AT91_PMC_RATIO);
+ writel(pwrtmg, soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+}
+
struct ramc_info {
void (*idle)(void);
unsigned int memctrl;
@@ -615,6 +639,7 @@ static const struct ramc_info ramc_infos[] __initconst = {
{ .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC},
{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
{ .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
+ { .idle = sama7g5_standby, },
};
static const struct of_device_id ramc_ids[] __initconst = {
@@ -622,7 +647,7 @@ static const struct of_device_id ramc_ids[] __initconst = {
{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
- { .compatible = "microchip,sama7g5-uddrc", },
+ { .compatible = "microchip,sama7g5-uddrc", .data = &ramc_infos[4], },
{ /*sentinel*/ }
};
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index fdb4f63ecde4..abe4ced33eda 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -159,7 +159,7 @@ sr_ena_1:
/* Switch to self-refresh. */
ldr tmp1, [r2, #UDDRC_PWRCTL]
- orr tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
+ orr tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
str tmp1, [r2, #UDDRC_PWRCTL]
sr_ena_2:
@@ -276,7 +276,7 @@ sr_dis_5:
/* Trigger self-refresh exit. */
ldr tmp1, [r2, #UDDRC_PWRCTL]
- bic tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
+ bic tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
str tmp1, [r2, #UDDRC_PWRCTL]
sr_dis_6:
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index bd3f82788ebc..8db655c3e321 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -185,7 +185,6 @@ config ARCH_BCM_53573
config ARCH_BCM_63XX
bool "Broadcom BCM63xx DSL SoC"
depends on ARCH_MULTI_V7
- depends on MMU
select ARCH_HAS_RESET_CONTROLLER
select ARM_ERRATA_754322
select ARM_ERRATA_764369 if SMP
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 7baa8c9427d5..b2394ddb0558 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
# Support for secure monitor traps
obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o
+CFLAGS_REMOVE_bcm_kona_smc.o += $(CC_FLAGS_FTRACE)
# BCM2835
ifeq ($(CONFIG_ARCH_BCM2835),y)
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index 31ccbcee2627..d36f6b8269c2 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -73,12 +73,12 @@ void __init dove_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-71.
*/
- orion_gpio_init(NULL, 0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
+ orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START, gpio0_irqs);
- orion_gpio_init(NULL, 32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
+ orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32, gpio1_irqs);
- orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0,
+ orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
}
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 2eaf2dbb8e81..2da5b60b59e2 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
/*
* Exynos3250 doesn't need to send smc command for secondary CPU boot
* because Exynos3250 removes WFE in secure mode.
+ *
+ * On Exynos5 devices the call is ignored by trustzone firmware.
*/
- if (soc_is_exynos3250())
+ if (!soc_is_exynos4210() && !soc_is_exynos4412())
return 0;
/*
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index cd861c57d5ad..fd0dbeb93357 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -35,7 +35,6 @@ static bool secure_firmware __ro_after_init;
*/
#define exynos_v7_exit_coherency_flush(level) \
asm volatile( \
- "stmfd sp!, {fp, ip}\n\t"\
"mrc p15, 0, r0, c1, c0, 0 @ get SCTLR\n\t" \
"bic r0, r0, #"__stringify(CR_C)"\n\t" \
"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \
@@ -50,11 +49,10 @@ static bool secure_firmware __ro_after_init;
"mcr p15, 0, r0, c1, c0, 1 @ set ACTLR\n\t" \
"isb\n\t" \
"dsb\n\t" \
- "ldmfd sp!, {fp, ip}" \
: \
: "Ir" (pmu_base_addr + S5P_INFORM0) \
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r9", "r10", "lr", "memory")
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", \
+ "r9", "r10", "ip", "lr", "memory")
static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
{
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index eee095f0e2f6..322495df271d 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -27,6 +27,91 @@
#include "common.h"
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/hardware/dec21285.h>
+
+static int dc21285_get_irq(void)
+{
+ void __iomem *irqstatus = (void __iomem *)CSR_IRQ_STATUS;
+ u32 mask = readl(irqstatus);
+
+ if (mask & IRQ_MASK_SDRAMPARITY)
+ return IRQ_SDRAMPARITY;
+
+ if (mask & IRQ_MASK_UART_RX)
+ return IRQ_CONRX;
+
+ if (mask & IRQ_MASK_DMA1)
+ return IRQ_DMA1;
+
+ if (mask & IRQ_MASK_DMA2)
+ return IRQ_DMA2;
+
+ if (mask & IRQ_MASK_IN0)
+ return IRQ_IN0;
+
+ if (mask & IRQ_MASK_IN1)
+ return IRQ_IN1;
+
+ if (mask & IRQ_MASK_IN2)
+ return IRQ_IN2;
+
+ if (mask & IRQ_MASK_IN3)
+ return IRQ_IN3;
+
+ if (mask & IRQ_MASK_PCI)
+ return IRQ_PCI;
+
+ if (mask & IRQ_MASK_DOORBELLHOST)
+ return IRQ_DOORBELLHOST;
+
+ if (mask & IRQ_MASK_I2OINPOST)
+ return IRQ_I2OINPOST;
+
+ if (mask & IRQ_MASK_TIMER1)
+ return IRQ_TIMER1;
+
+ if (mask & IRQ_MASK_TIMER2)
+ return IRQ_TIMER2;
+
+ if (mask & IRQ_MASK_TIMER3)
+ return IRQ_TIMER3;
+
+ if (mask & IRQ_MASK_UART_TX)
+ return IRQ_CONTX;
+
+ if (mask & IRQ_MASK_PCI_ABORT)
+ return IRQ_PCI_ABORT;
+
+ if (mask & IRQ_MASK_PCI_SERR)
+ return IRQ_PCI_SERR;
+
+ if (mask & IRQ_MASK_DISCARD_TIMER)
+ return IRQ_DISCARD_TIMER;
+
+ if (mask & IRQ_MASK_PCI_DPERR)
+ return IRQ_PCI_DPERR;
+
+ if (mask & IRQ_MASK_PCI_PERR)
+ return IRQ_PCI_PERR;
+
+ return 0;
+}
+
+static void dc21285_handle_irq(struct pt_regs *regs)
+{
+ int irq;
+ do {
+ irq = dc21285_get_irq();
+ if (!irq)
+ break;
+
+ generic_handle_irq(irq);
+ } while (1);
+}
+
+
unsigned int mem_fclk_21285 = 50000000;
EXPORT_SYMBOL(mem_fclk_21285);
@@ -108,6 +193,8 @@ static void __init __fb_init_irq(void)
void __init footbridge_init_irq(void)
{
+ set_handle_irq(dc21285_handle_irq);
+
__fb_init_irq();
if (!footbridge_cfn_mode())
diff --git a/arch/arm/mach-footbridge/include/mach/entry-macro.S b/arch/arm/mach-footbridge/include/mach/entry-macro.S
deleted file mode 100644
index dabbd5c54a78..000000000000
--- a/arch/arm/mach-footbridge/include/mach/entry-macro.S
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * arch/arm/mach-footbridge/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for footbridge-based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <asm/hardware/dec21285.h>
-
- .equ dc21285_high, ARMCSR_BASE & 0xff000000
- .equ dc21285_low, ARMCSR_BASE & 0x00ffffff
-
- .macro get_irqnr_preamble, base, tmp
- mov \base, #dc21285_high
- .if dc21285_low
- orr \base, \base, #dc21285_low
- .endif
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldr \irqstat, [\base, #0x180] @ get interrupts
-
- mov \irqnr, #IRQ_SDRAMPARITY
- tst \irqstat, #IRQ_MASK_SDRAMPARITY
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_UART_RX
- movne \irqnr, #IRQ_CONRX
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_DMA1
- movne \irqnr, #IRQ_DMA1
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_DMA2
- movne \irqnr, #IRQ_DMA2
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_IN0
- movne \irqnr, #IRQ_IN0
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_IN1
- movne \irqnr, #IRQ_IN1
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_IN2
- movne \irqnr, #IRQ_IN2
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_IN3
- movne \irqnr, #IRQ_IN3
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI
- movne \irqnr, #IRQ_PCI
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_DOORBELLHOST
- movne \irqnr, #IRQ_DOORBELLHOST
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_I2OINPOST
- movne \irqnr, #IRQ_I2OINPOST
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_TIMER1
- movne \irqnr, #IRQ_TIMER1
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_TIMER2
- movne \irqnr, #IRQ_TIMER2
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_TIMER3
- movne \irqnr, #IRQ_TIMER3
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_UART_TX
- movne \irqnr, #IRQ_CONTX
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI_ABORT
- movne \irqnr, #IRQ_PCI_ABORT
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI_SERR
- movne \irqnr, #IRQ_PCI_SERR
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_DISCARD_TIMER
- movne \irqnr, #IRQ_DISCARD_TIMER
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI_DPERR
- movne \irqnr, #IRQ_PCI_DPERR
- bne 1001f
-
- tst \irqstat, #IRQ_MASK_PCI_PERR
- movne \irqnr, #IRQ_PCI_PERR
-1001:
- .endm
-
diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h
index ecaf6e7388d9..985ad3a95671 100644
--- a/arch/arm/mach-footbridge/include/mach/hardware.h
+++ b/arch/arm/mach-footbridge/include/mach/hardware.h
@@ -21,32 +21,26 @@
* 0xf0000000 0x80000000 16MB ISA memory
*/
-#ifdef CONFIG_MMU
-#define MMU_IO(a, b) (a)
-#else
-#define MMU_IO(a, b) (b)
-#endif
-
#define XBUS_SIZE 0x00100000
-#define XBUS_BASE MMU_IO(0xff800000, 0x40000000)
+#define XBUS_BASE 0xff800000
#define ARMCSR_SIZE 0x00100000
-#define ARMCSR_BASE MMU_IO(0xfe000000, 0x42000000)
+#define ARMCSR_BASE 0xfe000000
#define WFLUSH_SIZE 0x00100000
-#define WFLUSH_BASE MMU_IO(0xfd000000, 0x78000000)
+#define WFLUSH_BASE 0xfd000000
#define PCIIACK_SIZE 0x00100000
-#define PCIIACK_BASE MMU_IO(0xfc000000, 0x79000000)
+#define PCIIACK_BASE 0xfc000000
#define PCICFG1_SIZE 0x01000000
-#define PCICFG1_BASE MMU_IO(0xfb000000, 0x7a000000)
+#define PCICFG1_BASE 0xfb000000
#define PCICFG0_SIZE 0x01000000
-#define PCICFG0_BASE MMU_IO(0xfa000000, 0x7b000000)
+#define PCICFG0_BASE 0xfa000000
#define PCIMEM_SIZE 0x01000000
-#define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000)
+#define PCIMEM_BASE 0xf0000000
#define XBUS_CS2 0x40012000
diff --git a/arch/arm/mach-footbridge/include/mach/io.h b/arch/arm/mach-footbridge/include/mach/io.h
deleted file mode 100644
index 4e18b921373f..000000000000
--- a/arch/arm/mach-footbridge/include/mach/io.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-footbridge/include/mach/io.h
- *
- * Copyright (C) 1997-1999 Russell King
- *
- * Modifications:
- * 06-12-1997 RMK Created.
- * 07-04-1999 RMK Major cleanup
- */
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-/*
- * Translation of various i/o addresses to host addresses for !CONFIG_MMU
- */
-#define PCIO_BASE 0x7c000000
-#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
-
-#endif
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index f296bac467c8..c5a59158722b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -227,6 +227,13 @@ config SOC_IMX7ULP
help
This enables support for Freescale i.MX7 Ultra Low Power processor.
+config SOC_IMXRT
+ bool "i.MXRT support"
+ depends on ARM_SINGLE_ARMV7M
+ select ARMV7M_SYSTICK if ARM_SINGLE_ARMV7M
+ help
+ This enables support for Freescale i.MXRT Crossover processor.
+
config SOC_VF610
bool "Vybrid Family VF610 support"
select ARM_GIC if ARCH_MULTI_V7
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d5291ed9186a..6fb3965b9ae6 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -63,6 +63,8 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
+obj-$(CONFIG_SOC_IMXRT) += mach-imxrt.o
+
obj-$(CONFIG_SOC_VF610) += mach-vf610.o
obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
diff --git a/arch/arm/mach-imx/mach-imxrt.c b/arch/arm/mach-imx/mach-imxrt.c
new file mode 100644
index 000000000000..2063a3059c84
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imxrt.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
+ */
+
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+#include <asm/v7m.h>
+
+static const char *const imxrt_compat[] __initconst = {
+ "fsl,imxrt1050",
+ NULL
+};
+
+DT_MACHINE_START(IMXRTDT, "IMXRT (Device Tree Support)")
+ .dt_compat = imxrt_compat,
+ .restart = armv7m_restart,
+MACHINE_END
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 63a0ca82659a..d61ea616cf8e 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -42,24 +42,12 @@ config INTEGRATOR_IMPD1
allows ARM(R) Ltd PrimeCells to be developed and evaluated.
The IM-PD1 can be found on the Integrator/PP2 platform.
-config INTEGRATOR_CM7TDMI
- bool "Integrator/CM7TDMI core module"
- depends on ARCH_INTEGRATOR_AP
- depends on ARCH_MULTI_V4 && !MMU
- select CPU_ARM7TDMI
-
config INTEGRATOR_CM720T
bool "Integrator/CM720T core module"
depends on ARCH_INTEGRATOR_AP
depends on ARCH_MULTI_V4T
select CPU_ARM720T
-config INTEGRATOR_CM740T
- bool "Integrator/CM740T core module"
- depends on ARCH_INTEGRATOR_AP
- depends on ARCH_MULTI_V4T && !MMU
- select CPU_ARM740T
-
config INTEGRATOR_CM920T
bool "Integrator/CM920T core module"
depends on ARCH_INTEGRATOR_AP
@@ -78,23 +66,6 @@ config INTEGRATOR_CM926EJS
depends on ARCH_MULTI_V5
select CPU_ARM926T
-config INTEGRATOR_CM940T
- bool "Integrator/CM940T core module"
- depends on ARCH_INTEGRATOR_AP
- depends on ARCH_MULTI_V4T && !MMU
- select CPU_ARM940T
-
-config INTEGRATOR_CM946ES
- bool "Integrator/CM946E-S core module"
- depends on ARCH_INTEGRATOR_AP
- depends on ARCH_MULTI_V5 && !MMU
- select CPU_ARM946E
-
-config INTEGRATOR_CM966ES
- bool "Integrator/CM966E-S core module"
- depends on ARCH_INTEGRATOR_AP
- depends on BROKEN # no kernel support
-
config INTEGRATOR_CM10200E_REV0
bool "Integrator/CM10200E rev.0 core module"
depends on ARCH_INTEGRATOR_AP && n
@@ -127,7 +98,7 @@ config INTEGRATOR_CM1136JFS
config ARCH_INTEGRATOR_CP
bool "Support Integrator/CP platform"
- depends on (!MMU || ARCH_MULTI_V5 || ARCH_MULTI_V6)
+ depends on ARCH_MULTI_V5 || ARCH_MULTI_V6
select ARM_TIMER_SP804
select SERIAL_AMBA_PL011 if TTY
select SERIAL_AMBA_PL011_CONSOLE if TTY
@@ -135,12 +106,6 @@ config ARCH_INTEGRATOR_CP
help
Include support for the ARM(R) Integrator CP platform.
-config INTEGRATOR_CT7T
- bool "Integrator/CT7TD (ARM7TDMI) core tile"
- depends on ARCH_INTEGRATOR_CP
- depends on ARCH_MULTI_V4T && !MMU
- select CPU_ARM7TDMI
-
config INTEGRATOR_CT926
bool "Integrator/CT926 (ARM926EJ-S) core tile"
depends on ARCH_INTEGRATOR_CP
diff --git a/arch/arm/mach-integrator/hardware.h b/arch/arm/mach-integrator/hardware.h
index 4d6ade3dd4ee..81ce09e3ad45 100644
--- a/arch/arm/mach-integrator/hardware.h
+++ b/arch/arm/mach-integrator/hardware.h
@@ -16,12 +16,7 @@
#define IO_START INTEGRATOR_HDR_BASE // PA of IO
/* macro to get at IO space when running virtually */
-#ifdef CONFIG_MMU
#define IO_ADDRESS(x) (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
-#else
-#define IO_ADDRESS(x) (x)
-#endif
-
#define __io_address(n) ((void __iomem *)IO_ADDRESS(n))
/*
diff --git a/arch/arm/mach-iop32x/cp6.c b/arch/arm/mach-iop32x/cp6.c
index ec74b07fb7e3..2882674a1c39 100644
--- a/arch/arm/mach-iop32x/cp6.c
+++ b/arch/arm/mach-iop32x/cp6.c
@@ -7,7 +7,7 @@
#include <asm/traps.h>
#include <asm/ptrace.h>
-static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+void iop_enable_cp6(void)
{
u32 temp;
@@ -16,7 +16,15 @@ static int cp6_trap(struct pt_regs *regs, unsigned int instr)
"mrc p15, 0, %0, c15, c1, 0\n\t"
"orr %0, %0, #(1 << 6)\n\t"
"mcr p15, 0, %0, c15, c1, 0\n\t"
+ "mrc p15, 0, %0, c15, c1, 0\n\t"
+ "mov %0, %0\n\t"
+ "sub pc, pc, #4 @ cp_wait\n\t"
: "=r"(temp));
+}
+
+static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+{
+ iop_enable_cp6();
return 0;
}
diff --git a/arch/arm/mach-iop32x/include/mach/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S
deleted file mode 100644
index 8e6766d4621e..000000000000
--- a/arch/arm/mach-iop32x/include/mach/entry-macro.S
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mach-iop32x/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for IOP32x-based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
- .macro get_irqnr_preamble, base, tmp
- mrc p15, 0, \tmp, c15, c1, 0
- orr \tmp, \tmp, #(1 << 6)
- mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
- mrc p15, 0, \tmp, c15, c1, 0
- mov \tmp, \tmp
- sub pc, pc, #4 @ cp_wait
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC
- cmp \irqstat, #0
- clzne \irqnr, \irqstat
- rsbne \irqnr, \irqnr, #31
- .endm
-
- .macro arch_ret_to_user, tmp1, tmp2
- mrc p15, 0, \tmp1, c15, c1, 0
- ands \tmp2, \tmp1, #(1 << 6)
- bicne \tmp1, \tmp1, #(1 << 6)
- mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
- .endm
diff --git a/arch/arm/mach-iop32x/include/mach/irqs.h b/arch/arm/mach-iop32x/include/mach/irqs.h
index c4e78df428e8..e09ae5f48aec 100644
--- a/arch/arm/mach-iop32x/include/mach/irqs.h
+++ b/arch/arm/mach-iop32x/include/mach/irqs.h
@@ -9,6 +9,6 @@
#ifndef __IRQS_H
#define __IRQS_H
-#define NR_IRQS 32
+#define NR_IRQS 33
#endif
diff --git a/arch/arm/mach-iop32x/iop3xx.h b/arch/arm/mach-iop32x/iop3xx.h
index 46b4b34a4ad2..a6ec7ebadb35 100644
--- a/arch/arm/mach-iop32x/iop3xx.h
+++ b/arch/arm/mach-iop32x/iop3xx.h
@@ -225,6 +225,7 @@ extern int iop3xx_get_init_atu(void);
#include <linux/reboot.h>
void iop3xx_map_io(void);
+void iop_enable_cp6(void);
void iop_init_cp6_handler(void);
void iop_init_time(unsigned long tickrate);
void iop3xx_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 2d48bf1398c1..6dca7e97d81f 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -29,17 +29,26 @@ static void intstr_write(u32 val)
asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val));
}
+static u32 iintsrc_read(void)
+{
+ int irq;
+
+ asm volatile("mrc p6, 0, %0, c8, c0, 0" : "=r" (irq));
+
+ return irq;
+}
+
static void
iop32x_irq_mask(struct irq_data *d)
{
- iop32x_mask &= ~(1 << d->irq);
+ iop32x_mask &= ~(1 << (d->irq - 1));
intctl_write(iop32x_mask);
}
static void
iop32x_irq_unmask(struct irq_data *d)
{
- iop32x_mask |= 1 << d->irq;
+ iop32x_mask |= 1 << (d->irq - 1);
intctl_write(iop32x_mask);
}
@@ -50,11 +59,25 @@ struct irq_chip ext_chip = {
.irq_unmask = iop32x_irq_unmask,
};
+static void iop_handle_irq(struct pt_regs *regs)
+{
+ u32 mask;
+
+ iop_enable_cp6();
+
+ do {
+ mask = iintsrc_read();
+ if (mask)
+ generic_handle_irq(fls(mask));
+ } while (mask);
+}
+
void __init iop32x_init_irq(void)
{
int i;
iop_init_cp6_handler();
+ set_handle_irq(iop_handle_irq);
intctl_write(0);
intstr_write(0);
@@ -65,7 +88,7 @@ void __init iop32x_init_irq(void)
machine_is_em7210())
*IOP3XX_PCIIRSR = 0x0f;
- for (i = 0; i < NR_IRQS; i++) {
+ for (i = 1; i < NR_IRQS; i++) {
irq_set_chip_and_handler(i, &ext_chip, handle_level_irq);
irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE);
}
diff --git a/arch/arm/mach-iop32x/irqs.h b/arch/arm/mach-iop32x/irqs.h
index 69858e4e905d..e1dfc8b4e7d7 100644
--- a/arch/arm/mach-iop32x/irqs.h
+++ b/arch/arm/mach-iop32x/irqs.h
@@ -7,36 +7,40 @@
#ifndef __IOP32X_IRQS_H
#define __IOP32X_IRQS_H
+/* Interrupts in Linux start at 1, hardware starts at 0 */
+
+#define IOP_IRQ(x) ((x) + 1)
+
/*
* IOP80321 chipset interrupts
*/
-#define IRQ_IOP32X_DMA0_EOT 0
-#define IRQ_IOP32X_DMA0_EOC 1
-#define IRQ_IOP32X_DMA1_EOT 2
-#define IRQ_IOP32X_DMA1_EOC 3
-#define IRQ_IOP32X_AA_EOT 6
-#define IRQ_IOP32X_AA_EOC 7
-#define IRQ_IOP32X_CORE_PMON 8
-#define IRQ_IOP32X_TIMER0 9
-#define IRQ_IOP32X_TIMER1 10
-#define IRQ_IOP32X_I2C_0 11
-#define IRQ_IOP32X_I2C_1 12
-#define IRQ_IOP32X_MESSAGING 13
-#define IRQ_IOP32X_ATU_BIST 14
-#define IRQ_IOP32X_PERFMON 15
-#define IRQ_IOP32X_CORE_PMU 16
-#define IRQ_IOP32X_BIU_ERR 17
-#define IRQ_IOP32X_ATU_ERR 18
-#define IRQ_IOP32X_MCU_ERR 19
-#define IRQ_IOP32X_DMA0_ERR 20
-#define IRQ_IOP32X_DMA1_ERR 21
-#define IRQ_IOP32X_AA_ERR 23
-#define IRQ_IOP32X_MSG_ERR 24
-#define IRQ_IOP32X_SSP 25
-#define IRQ_IOP32X_XINT0 27
-#define IRQ_IOP32X_XINT1 28
-#define IRQ_IOP32X_XINT2 29
-#define IRQ_IOP32X_XINT3 30
-#define IRQ_IOP32X_HPI 31
+#define IRQ_IOP32X_DMA0_EOT IOP_IRQ(0)
+#define IRQ_IOP32X_DMA0_EOC IOP_IRQ(1)
+#define IRQ_IOP32X_DMA1_EOT IOP_IRQ(2)
+#define IRQ_IOP32X_DMA1_EOC IOP_IRQ(3)
+#define IRQ_IOP32X_AA_EOT IOP_IRQ(6)
+#define IRQ_IOP32X_AA_EOC IOP_IRQ(7)
+#define IRQ_IOP32X_CORE_PMON IOP_IRQ(8)
+#define IRQ_IOP32X_TIMER0 IOP_IRQ(9)
+#define IRQ_IOP32X_TIMER1 IOP_IRQ(10)
+#define IRQ_IOP32X_I2C_0 IOP_IRQ(11)
+#define IRQ_IOP32X_I2C_1 IOP_IRQ(12)
+#define IRQ_IOP32X_MESSAGING IOP_IRQ(13)
+#define IRQ_IOP32X_ATU_BIST IOP_IRQ(14)
+#define IRQ_IOP32X_PERFMON IOP_IRQ(15)
+#define IRQ_IOP32X_CORE_PMU IOP_IRQ(16)
+#define IRQ_IOP32X_BIU_ERR IOP_IRQ(17)
+#define IRQ_IOP32X_ATU_ERR IOP_IRQ(18)
+#define IRQ_IOP32X_MCU_ERR IOP_IRQ(19)
+#define IRQ_IOP32X_DMA0_ERR IOP_IRQ(20)
+#define IRQ_IOP32X_DMA1_ERR IOP_IRQ(21)
+#define IRQ_IOP32X_AA_ERR IOP_IRQ(23)
+#define IRQ_IOP32X_MSG_ERR IOP_IRQ(24)
+#define IRQ_IOP32X_SSP IOP_IRQ(25)
+#define IRQ_IOP32X_XINT0 IOP_IRQ(27)
+#define IRQ_IOP32X_XINT1 IOP_IRQ(28)
+#define IRQ_IOP32X_XINT2 IOP_IRQ(29)
+#define IRQ_IOP32X_XINT3 IOP_IRQ(30)
+#define IRQ_IOP32X_HPI IOP_IRQ(31)
#endif
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 4c787b4be62b..f41ba3f42fc8 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -17,63 +17,6 @@ config MACH_IXP4XX_OF
help
Say 'Y' here to support Device Tree-based IXP4xx platforms.
-config MACH_GATEWAY7001
- bool "Gateway 7001"
- depends on IXP4XX_PCI_LEGACY
- help
- Say 'Y' here if you want your kernel to support Gateway's
- 7001 Access Point. For more information on this platform,
- see http://openwrt.org
-
-config MACH_GORAMO_MLR
- bool "GORAMO Multi Link Router"
- depends on IXP4XX_PCI_LEGACY
- help
- Say 'Y' here if you want your kernel to support GORAMO
- MultiLink router.
-
-config ARCH_PRPMC1100
- bool "PrPMC1100"
- help
- Say 'Y' here if you want your kernel to support the Motorola
- PrPCM1100 Processor Mezanine Module. For more information on
- this platform, see <file:Documentation/arm/ixp4xx.rst>.
-
-comment "IXP4xx Options"
-
-config IXP4XX_PCI_LEGACY
- bool "IXP4xx legacy PCI driver support"
- depends on PCI
- help
- Selects legacy PCI driver.
- Not recommended for new development.
-
-config IXP4XX_INDIRECT_PCI
- bool "Use indirect PCI memory access"
- depends on IXP4XX_PCI_LEGACY
- help
- IXP4xx provides two methods of accessing PCI memory space:
-
- 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
- To access PCI via this space, we simply ioremap() the BAR
- into the kernel and we can use the standard read[bwl]/write[bwl]
- macros. This is the preferred method due to speed but it
- limits the system to just 64MB of PCI memory. This can be
- problematic if using video cards and other memory-heavy devices.
-
- 2) If > 64MB of memory space is required, the IXP4xx can be
- configured to use indirect registers to access the whole PCI
- memory space. This currently allows for up to 1 GB (0x10000000
- to 0x4FFFFFFF) of memory on the bus. The disadvantage of this
- is that every PCI access requires three local register accesses
- plus a spinlock, but in some cases the performance hit is
- acceptable. In addition, you cannot mmap() PCI devices in this
- case due to the indirect nature of the PCI window.
-
- By default, the direct method is used. Choose this option if you
- need to use the indirect method instead. If you don't know
- what you need, leave this option unselected.
-
endmenu
endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index b241094c9649..3d1c9d854c7f 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -1,19 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-
-obj-pci-y :=
-obj-pci-n :=
-
-# Device tree platform
-obj-pci-$(CONFIG_MACH_IXP4XX_OF) += ixp4xx-of.o
-
-obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o
-
-obj-y += common.o
-
-obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
-obj-$(CONFIG_MACH_GORAMO_MLR) += goramo_mlr.o
-
-obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
+obj-y += ixp4xx-of.o
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
deleted file mode 100644
index 893c19c254e3..000000000000
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ /dev/null
@@ -1,451 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-ixp4xx/common-pci.c
- *
- * IXP4XX PCI routines for all platforms
- *
- * Maintainer: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003 Greg Ungerer <gerg@snapgear.com>
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/export.h>
-#include <asm/dma-mapping.h>
-
-#include <asm/cputype.h>
-#include <asm/irq.h>
-#include <linux/sizes.h>
-#include <asm/mach/pci.h>
-#include <mach/hardware.h>
-
-
-/*
- * IXP4xx PCI read function is dependent on whether we are
- * running A0 or B0 (AppleGate) silicon.
- */
-int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
-
-/*
- * Base address for PCI register region
- */
-unsigned long ixp4xx_pci_reg_base = 0;
-
-/*
- * PCI cfg an I/O routines are done by programming a
- * command/byte enable register, and then read/writing
- * the data from a data register. We need to ensure
- * these transactions are atomic or we will end up
- * with corrupt data on the bus or in a driver.
- */
-static DEFINE_RAW_SPINLOCK(ixp4xx_pci_lock);
-
-/*
- * Read from PCI config space
- */
-static void crp_read(u32 ad_cbe, u32 *data)
-{
- unsigned long flags;
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
- *PCI_CRP_AD_CBE = ad_cbe;
- *data = *PCI_CRP_RDATA;
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-}
-
-/*
- * Write to PCI config space
- */
-static void crp_write(u32 ad_cbe, u32 data)
-{
- unsigned long flags;
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
- *PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
- *PCI_CRP_WDATA = data;
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-}
-
-static inline int check_master_abort(void)
-{
- /* check Master Abort bit after access */
- unsigned long isr = *PCI_ISR;
-
- if (isr & PCI_ISR_PFE) {
- /* make sure the Master Abort bit is reset */
- *PCI_ISR = PCI_ISR_PFE;
- pr_debug("%s failed\n", __func__);
- return 1;
- }
-
- return 0;
-}
-
-int ixp4xx_pci_read_errata(u32 addr, u32 cmd, u32* data)
-{
- unsigned long flags;
- int retval = 0;
- int i;
-
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
- *PCI_NP_AD = addr;
-
- /*
- * PCI workaround - only works if NP PCI space reads have
- * no side effects!!! Read 8 times. last one will be good.
- */
- for (i = 0; i < 8; i++) {
- *PCI_NP_CBE = cmd;
- *data = *PCI_NP_RDATA;
- *data = *PCI_NP_RDATA;
- }
-
- if(check_master_abort())
- retval = 1;
-
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
- return retval;
-}
-
-int ixp4xx_pci_read_no_errata(u32 addr, u32 cmd, u32* data)
-{
- unsigned long flags;
- int retval = 0;
-
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
- *PCI_NP_AD = addr;
-
- /* set up and execute the read */
- *PCI_NP_CBE = cmd;
-
- /* the result of the read is now in NP_RDATA */
- *data = *PCI_NP_RDATA;
-
- if(check_master_abort())
- retval = 1;
-
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
- return retval;
-}
-
-int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data)
-{
- unsigned long flags;
- int retval = 0;
-
- raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
- *PCI_NP_AD = addr;
-
- /* set up the write */
- *PCI_NP_CBE = cmd;
-
- /* execute the write by writing to NP_WDATA */
- *PCI_NP_WDATA = data;
-
- if(check_master_abort())
- retval = 1;
-
- raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
- return retval;
-}
-
-static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where)
-{
- u32 addr;
- if (!bus_num) {
- /* type 0 */
- addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) |
- (where & ~3);
- } else {
- /* type 1 */
- addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) |
- ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
- }
- return addr;
-}
-
-/*
- * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
- * 0 and 3 are not valid indexes...
- */
-static u32 bytemask[] = {
- /*0*/ 0,
- /*1*/ 0xff,
- /*2*/ 0xffff,
- /*3*/ 0,
- /*4*/ 0xffffffff,
-};
-
-static u32 local_byte_lane_enable_bits(u32 n, int size)
-{
- if (size == 1)
- return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL;
- if (size == 2)
- return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL;
- if (size == 4)
- return 0;
- return 0xffffffff;
-}
-
-static int local_read_config(int where, int size, u32 *value)
-{
- u32 n, data;
- pr_debug("local_read_config from %d size %d\n", where, size);
- n = where % 4;
- crp_read(where & ~3, &data);
- *value = (data >> (8*n)) & bytemask[size];
- pr_debug("local_read_config read %#x\n", *value);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int local_write_config(int where, int size, u32 value)
-{
- u32 n, byte_enables, data;
- pr_debug("local_write_config %#x to %d size %d\n", value, where, size);
- n = where % 4;
- byte_enables = local_byte_lane_enable_bits(n, size);
- if (byte_enables == 0xffffffff)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- data = value << (8*n);
- crp_write((where & ~3) | byte_enables, data);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static u32 byte_lane_enable_bits(u32 n, int size)
-{
- if (size == 1)
- return (0xf & ~BIT(n)) << 4;
- if (size == 2)
- return (0xf & ~(BIT(n) | BIT(n+1))) << 4;
- if (size == 4)
- return 0;
- return 0xffffffff;
-}
-
-static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
- u32 n, byte_enables, addr, data;
- u8 bus_num = bus->number;
-
- pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size,
- bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-
- *value = 0xffffffff;
- n = where % 4;
- byte_enables = byte_lane_enable_bits(n, size);
- if (byte_enables == 0xffffffff)
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- addr = ixp4xx_config_addr(bus_num, devfn, where);
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = (data >> (8*n)) & bytemask[size];
- pr_debug("read_config_byte read %#x\n", *value);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
- u32 n, byte_enables, addr, data;
- u8 bus_num = bus->number;
-
- pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where,
- size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-
- n = where % 4;
- byte_enables = byte_lane_enable_bits(n, size);
- if (byte_enables == 0xffffffff)
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- addr = ixp4xx_config_addr(bus_num, devfn, where);
- data = value << (8*n);
- if (ixp4xx_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops ixp4xx_ops = {
- .read = ixp4xx_pci_read_config,
- .write = ixp4xx_pci_write_config,
-};
-
-/*
- * PCI abort handler
- */
-static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
- u32 isr, status;
-
- isr = *PCI_ISR;
- local_read_config(PCI_STATUS, 2, &status);
- pr_debug("PCI: abort_handler addr = %#lx, isr = %#x, "
- "status = %#x\n", addr, isr, status);
-
- /* make sure the Master Abort bit is reset */
- *PCI_ISR = PCI_ISR_PFE;
- status |= PCI_STATUS_REC_MASTER_ABORT;
- local_write_config(PCI_STATUS, 2, status);
-
- /*
- * If it was an imprecise abort, then we need to correct the
- * return address to be _after_ the instruction.
- */
- if (fsr & (1 << 10))
- regs->ARM_pc += 4;
-
- return 0;
-}
-
-void __init ixp4xx_pci_preinit(void)
-{
- unsigned long cpuid = read_cpuid_id();
-
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
- pcibios_min_mem = 0x10000000; /* 1 GB of indirect PCI MMIO space */
-#else
- pcibios_min_mem = 0x48000000; /* 64 MB of PCI MMIO space */
-#endif
- /*
- * Determine which PCI read method to use.
- * Rev 0 IXP425 requires workaround.
- */
- if (!(cpuid & 0xf) && cpu_is_ixp42x()) {
- printk("PCI: IXP42x A0 silicon detected - "
- "PCI Non-Prefetch Workaround Enabled\n");
- ixp4xx_pci_read = ixp4xx_pci_read_errata;
- } else
- ixp4xx_pci_read = ixp4xx_pci_read_no_errata;
-
-
- /* hook in our fault handler for PCI errors */
- hook_fault_code(16+6, abort_handler, SIGBUS, 0,
- "imprecise external abort");
-
- pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
-
- /*
- * We use identity AHB->PCI address translation
- * in the 0x48000000 to 0x4bffffff address space
- */
- *PCI_PCIMEMBASE = 0x48494A4B;
-
- /*
- * We also use identity PCI->AHB address translation
- * in 4 16MB BARs that begin at the physical memory start
- */
- *PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
- ((PHYS_OFFSET & 0xFF000000) >> 8) +
- ((PHYS_OFFSET & 0xFF000000) >> 16) +
- ((PHYS_OFFSET & 0xFF000000) >> 24) +
- 0x00010203;
-
- if (*PCI_CSR & PCI_CSR_HOST) {
- printk("PCI: IXP4xx is host\n");
-
- pr_debug("setup BARs in controller\n");
-
- /*
- * We configure the PCI inbound memory windows to be
- * 1:1 mapped to SDRAM
- */
- local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
- local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
- local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
- local_write_config(PCI_BASE_ADDRESS_3, 4,
- PHYS_OFFSET + SZ_32M + SZ_16M);
-
- /*
- * Enable CSR window at 64 MiB to allow PCI masters
- * to continue prefetching past 64 MiB boundary.
- */
- local_write_config(PCI_BASE_ADDRESS_4, 4, PHYS_OFFSET + SZ_64M);
-
- /*
- * Enable the IO window to be way up high, at 0xfffffc00
- */
- local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
- local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */
- } else {
- printk("PCI: IXP4xx is target - No bus scan performed\n");
- }
-
- printk("PCI: IXP4xx Using %s access for memory space\n",
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- "direct"
-#else
- "indirect"
-#endif
- );
-
- pr_debug("clear error bits in ISR\n");
- *PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE;
-
- /*
- * Set Initialize Complete in PCI Control Register: allow IXP4XX to
- * respond to PCI configuration cycles. Specify that the AHB bus is
- * operating in big endian mode. Set up byte lane swapping between
- * little-endian PCI and the big-endian AHB bus
- */
-#ifdef __ARMEB__
- *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
-#else
- *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE;
-#endif
-
- pr_debug("DONE\n");
-}
-
-int ixp4xx_setup(int nr, struct pci_sys_data *sys)
-{
- struct resource *res;
-
- if (nr >= 1)
- return 0;
-
- res = kcalloc(2, sizeof(*res), GFP_KERNEL);
- if (res == NULL) {
- /*
- * If we're out of memory this early, something is wrong,
- * so we might as well catch it here.
- */
- panic("PCI: unable to allocate resources?\n");
- }
-
- local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-
- res[0].name = "PCI I/O Space";
- res[0].start = 0x00000000;
- res[0].end = 0x0000ffff;
- res[0].flags = IORESOURCE_IO;
-
- res[1].name = "PCI Memory Space";
- res[1].start = PCIBIOS_MIN_MEM;
- res[1].end = PCIBIOS_MAX_MEM;
- res[1].flags = IORESOURCE_MEM;
-
- request_resource(&ioport_resource, &res[0]);
- request_resource(&iomem_resource, &res[1]);
-
- pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
- pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
-
- return 1;
-}
-
-EXPORT_SYMBOL(ixp4xx_pci_read);
-EXPORT_SYMBOL(ixp4xx_pci_write);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
deleted file mode 100644
index cdc720f54daa..000000000000
--- a/arch/arm/mach-ixp4xx/common.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/common.c
- *
- * Generic code shared across all IXP4XX platforms
- *
- * Maintainer: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright 2002 (c) Intel Corporation
- * Copyright 2003-2004 (c) MontaVista, Software, Inc.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/io.h>
-#include <linux/export.h>
-#include <linux/cpu.h>
-#include <linux/pci.h>
-#include <linux/sched_clock.h>
-#include <linux/soc/ixp4xx/cpu.h>
-#include <linux/irqchip/irq-ixp4xx.h>
-#include <linux/platform_data/timer-ixp4xx.h>
-#include <linux/dma-map-ops.h>
-#include <mach/udc.h>
-#include <mach/hardware.h>
-#include <linux/uaccess.h>
-#include <asm/page.h>
-#include <asm/exception.h>
-#include <asm/irq.h>
-#include <asm/system_misc.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-
-#include "irqs.h"
-
-u32 ixp4xx_read_feature_bits(void)
-{
- u32 val = ~__raw_readl(IXP4XX_EXP_CFG2);
-
- if (cpu_is_ixp42x_rev_a0())
- return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
- IXP4XX_FEATURE_AES);
- if (cpu_is_ixp42x())
- return val & IXP42X_FEATURE_MASK;
- if (cpu_is_ixp43x())
- return val & IXP43X_FEATURE_MASK;
- return val & IXP46X_FEATURE_MASK;
-}
-EXPORT_SYMBOL(ixp4xx_read_feature_bits);
-
-void ixp4xx_write_feature_bits(u32 value)
-{
- __raw_writel(~value, IXP4XX_EXP_CFG2);
-}
-EXPORT_SYMBOL(ixp4xx_write_feature_bits);
-
-#define IXP4XX_TIMER_FREQ 66666000
-
-/*************************************************************************
- * IXP4xx chipset I/O mapping
- *************************************************************************/
-static struct map_desc ixp4xx_io_desc[] __initdata = {
- { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
- .virtual = (unsigned long)IXP4XX_PERIPHERAL_BASE_VIRT,
- .pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
- .length = IXP4XX_PERIPHERAL_REGION_SIZE,
- .type = MT_DEVICE
- }, { /* Expansion Bus Config Registers */
- .virtual = (unsigned long)IXP4XX_EXP_CFG_BASE_VIRT,
- .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
- .length = IXP4XX_EXP_CFG_REGION_SIZE,
- .type = MT_DEVICE
- }, { /* PCI Registers */
- .virtual = (unsigned long)IXP4XX_PCI_CFG_BASE_VIRT,
- .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
- .length = IXP4XX_PCI_CFG_REGION_SIZE,
- .type = MT_DEVICE
- },
-};
-
-void __init ixp4xx_map_io(void)
-{
- iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
-}
-
-void __init ixp4xx_init_irq(void)
-{
- /*
- * ixp4xx does not implement the XScale PWRMODE register
- * so it must not call cpu_do_idle().
- */
- cpu_idle_poll_ctrl(true);
-
- ixp4xx_irq_init(IXP4XX_INTC_BASE_PHYS,
- (cpu_is_ixp46x() || cpu_is_ixp43x()));
-}
-
-void __init ixp4xx_timer_init(void)
-{
- return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
- IRQ_IXP4XX_TIMER1,
- IXP4XX_TIMER_FREQ);
-}
-
-static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
-
-void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info)
-{
- memcpy(&ixp4xx_udc_info, info, sizeof *info);
-}
-
-static struct resource ixp4xx_udc_resources[] = {
- [0] = {
- .start = 0xc800b000,
- .end = 0xc800bfff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_IXP4XX_USB,
- .end = IRQ_IXP4XX_USB,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource ixp4xx_gpio_resource[] = {
- {
- .start = IXP4XX_GPIO_BASE_PHYS,
- .end = IXP4XX_GPIO_BASE_PHYS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device ixp4xx_gpio_device = {
- .name = "ixp4xx-gpio",
- .id = -1,
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = ixp4xx_gpio_resource,
- .num_resources = ARRAY_SIZE(ixp4xx_gpio_resource),
-};
-
-/*
- * USB device controller. The IXP4xx uses the same controller as PXA25X,
- * so we just use the same device.
- */
-static struct platform_device ixp4xx_udc_device = {
- .name = "pxa25x-udc",
- .id = -1,
- .num_resources = 2,
- .resource = ixp4xx_udc_resources,
- .dev = {
- .platform_data = &ixp4xx_udc_info,
- },
-};
-
-static struct resource ixp4xx_npe_resources[] = {
- {
- .start = IXP4XX_NPEA_BASE_PHYS,
- .end = IXP4XX_NPEA_BASE_PHYS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IXP4XX_NPEB_BASE_PHYS,
- .end = IXP4XX_NPEB_BASE_PHYS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IXP4XX_NPEC_BASE_PHYS,
- .end = IXP4XX_NPEC_BASE_PHYS + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-
-};
-
-static struct platform_device ixp4xx_npe_device = {
- .name = "ixp4xx-npe",
- .id = -1,
- .num_resources = ARRAY_SIZE(ixp4xx_npe_resources),
- .resource = ixp4xx_npe_resources,
-};
-
-static struct resource ixp4xx_qmgr_resources[] = {
- {
- .start = IXP4XX_QMGR_BASE_PHYS,
- .end = IXP4XX_QMGR_BASE_PHYS + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IRQ_IXP4XX_QM1,
- .end = IRQ_IXP4XX_QM1,
- .flags = IORESOURCE_IRQ,
- },
- {
- .start = IRQ_IXP4XX_QM2,
- .end = IRQ_IXP4XX_QM2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device ixp4xx_qmgr_device = {
- .name = "ixp4xx-qmgr",
- .id = -1,
- .num_resources = ARRAY_SIZE(ixp4xx_qmgr_resources),
- .resource = ixp4xx_qmgr_resources,
-};
-
-static struct platform_device *ixp4xx_devices[] __initdata = {
- &ixp4xx_npe_device,
- &ixp4xx_qmgr_device,
- &ixp4xx_gpio_device,
- &ixp4xx_udc_device,
-};
-
-static struct resource ixp46x_i2c_resources[] = {
- [0] = {
- .start = 0xc8011000,
- .end = 0xc801101c,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_IXP4XX_I2C,
- .end = IRQ_IXP4XX_I2C,
- .flags = IORESOURCE_IRQ
- }
-};
-
-/* A single 32-bit register on IXP46x */
-#define IXP4XX_HWRANDOM_BASE_PHYS 0x70002100
-
-static struct resource ixp46x_hwrandom_resource[] = {
- {
- .start = IXP4XX_HWRANDOM_BASE_PHYS,
- .end = IXP4XX_HWRANDOM_BASE_PHYS + 0x3,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device ixp46x_hwrandom_device = {
- .name = "ixp4xx-hwrandom",
- .id = -1,
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = ixp46x_hwrandom_resource,
- .num_resources = ARRAY_SIZE(ixp46x_hwrandom_resource),
-};
-
-/*
- * I2C controller. The IXP46x uses the same block as the IOP3xx, so
- * we just use the same device name.
- */
-static struct platform_device ixp46x_i2c_controller = {
- .name = "IOP3xx-I2C",
- .id = 0,
- .num_resources = 2,
- .resource = ixp46x_i2c_resources
-};
-
-static struct resource ixp46x_ptp_resources[] = {
- DEFINE_RES_MEM(IXP4XX_TIMESYNC_BASE_PHYS, SZ_4K),
- DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO8, "master"),
- DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO7, "slave"),
-};
-
-static struct platform_device ixp46x_ptp = {
- .name = "ptp-ixp46x",
- .id = -1,
- .resource = ixp46x_ptp_resources,
- .num_resources = ARRAY_SIZE(ixp46x_ptp_resources),
-};
-
-static struct platform_device *ixp46x_devices[] __initdata = {
- &ixp46x_hwrandom_device,
- &ixp46x_i2c_controller,
- &ixp46x_ptp,
-};
-
-unsigned long ixp4xx_exp_bus_size;
-EXPORT_SYMBOL(ixp4xx_exp_bus_size);
-
-static struct platform_device_info ixp_dev_info __initdata = {
- .name = "ixp4xx_crypto",
- .id = 0,
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-static int __init ixp_crypto_register(void)
-{
- struct platform_device *pdev;
-
- if (!(~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH |
- IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) {
- printk(KERN_ERR "ixp_crypto: No HW crypto available\n");
- return -ENODEV;
- }
-
- pdev = platform_device_register_full(&ixp_dev_info);
- if (IS_ERR(pdev))
- return PTR_ERR(pdev);
-
- return 0;
-}
-
-void __init ixp4xx_sys_init(void)
-{
- ixp4xx_exp_bus_size = SZ_16M;
-
- platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
-
- if (IS_ENABLED(CONFIG_CRYPTO_DEV_IXP4XX))
- ixp_crypto_register();
-
- if (cpu_is_ixp46x()) {
- int region;
-
- platform_add_devices(ixp46x_devices,
- ARRAY_SIZE(ixp46x_devices));
-
- for (region = 0; region < 7; region++) {
- if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) {
- ixp4xx_exp_bus_size = SZ_32M;
- break;
- }
- }
- }
-
- printk("IXP4xx: Using %luMiB expansion bus window size\n",
- ixp4xx_exp_bus_size >> 20);
-}
-
-unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
-EXPORT_SYMBOL(ixp4xx_timer_freq);
-
-void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
-{
- if (mode == REBOOT_SOFT) {
- /* Jump into ROM at address 0 */
- soft_restart(0);
- } else {
- /* Use on-chip reset capability */
-
- /* set the "key" register to enable access to
- * "timer" and "enable" registers
- */
- *IXP4XX_OSWK = IXP4XX_WDT_KEY;
-
- /* write 0 to the timer register for an immediate reset */
- *IXP4XX_OSWT = 0;
-
- *IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
- }
-}
-
-#ifdef CONFIG_PCI
-static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
-{
- return (dma_addr + size) > SZ_64M;
-}
-
-static int ixp4xx_platform_notify_remove(struct device *dev)
-{
- if (dev_is_pci(dev))
- dmabounce_unregister_dev(dev);
-
- return 0;
-}
-#endif
-
-/*
- * Setup DMA mask to 64MB on PCI devices and 4 GB on all other things.
- */
-static int ixp4xx_platform_notify(struct device *dev)
-{
- dev->dma_mask = &dev->coherent_dma_mask;
-
-#ifdef CONFIG_PCI
- if (dev_is_pci(dev)) {
- dev->coherent_dma_mask = DMA_BIT_MASK(28); /* 64 MB */
- dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
- return 0;
- }
-#endif
-
- dev->coherent_dma_mask = DMA_BIT_MASK(32);
- return 0;
-}
-
-int dma_set_coherent_mask(struct device *dev, u64 mask)
-{
- if (dev_is_pci(dev))
- mask &= DMA_BIT_MASK(28); /* 64 MB */
-
- if ((mask & DMA_BIT_MASK(28)) == DMA_BIT_MASK(28)) {
- dev->coherent_dma_mask = mask;
- return 0;
- }
-
- return -EIO; /* device wanted sub-64MB mask */
-}
-EXPORT_SYMBOL(dma_set_coherent_mask);
-
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-/*
- * In the case of using indirect PCI, we simply return the actual PCI
- * address and our read/write implementation use that to drive the
- * access registers. If something outside of PCI is ioremap'd, we
- * fallback to the default.
- */
-
-static void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size,
- unsigned int mtype, void *caller)
-{
- if (!is_pci_memory(addr))
- return __arm_ioremap_caller(addr, size, mtype, caller);
-
- return (void __iomem *)addr;
-}
-
-static void ixp4xx_iounmap(volatile void __iomem *addr)
-{
- if (!is_pci_memory((__force u32)addr))
- __iounmap(addr);
-}
-#endif
-
-void __init ixp4xx_init_early(void)
-{
- platform_notify = ixp4xx_platform_notify;
-#ifdef CONFIG_PCI
- platform_notify_remove = ixp4xx_platform_notify_remove;
-#endif
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
- arch_ioremap_caller = ixp4xx_ioremap_caller;
- arch_iounmap = ixp4xx_iounmap;
-#endif
-}
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
deleted file mode 100644
index 3c3ee9dad6d8..000000000000
--- a/arch/arm/mach-ixp4xx/gateway7001-pci.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arch/mach-ixp4xx/gateway7001-pci.c
- *
- * PCI setup routines for Gateway 7001
- *
- * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
- *
- * based on coyote-pci.c:
- * Copyright (C) 2002 Jungo Software Technologies.
- * Copyright (C) 2003 MontaVista Softwrae, Inc.
- *
- * Maintainer: Imre Kaloz <kaloz@openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include <asm/mach/pci.h>
-
-#include "irqs.h"
-
-void __init gateway7001_pci_preinit(void)
-{
- irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
-
- ixp4xx_pci_preinit();
-}
-
-static int __init gateway7001_map_irq(const struct pci_dev *dev, u8 slot,
- u8 pin)
-{
- if (slot == 1)
- return IRQ_IXP4XX_GPIO11;
- else if (slot == 2)
- return IRQ_IXP4XX_GPIO10;
- else return -1;
-}
-
-struct hw_pci gateway7001_pci __initdata = {
- .nr_controllers = 1,
- .ops = &ixp4xx_ops,
- .preinit = gateway7001_pci_preinit,
- .setup = ixp4xx_setup,
- .map_irq = gateway7001_map_irq,
-};
-
-int __init gateway7001_pci_init(void)
-{
- if (machine_is_gateway7001())
- pci_common_init(&gateway7001_pci);
- return 0;
-}
-
-subsys_initcall(gateway7001_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
deleted file mode 100644
index 678e7dfff0e5..000000000000
--- a/arch/arm/mach-ixp4xx/gateway7001-setup.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/arm/mach-ixp4xx/gateway7001-setup.c
- *
- * Board setup for the Gateway 7001 board
- *
- * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
- *
- * based on coyote-setup.c:
- * Copyright (C) 2003-2005 MontaVista Software, Inc.
- *
- * Author: Imre Kaloz <Kaloz@openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_8250.h>
-
-#include <asm/types.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-
-#include "irqs.h"
-
-static struct flash_platform_data gateway7001_flash_data = {
- .map_name = "cfi_probe",
- .width = 2,
-};
-
-static struct resource gateway7001_flash_resource = {
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device gateway7001_flash = {
- .name = "IXP4XX-Flash",
- .id = 0,
- .dev = {
- .platform_data = &gateway7001_flash_data,
- },
- .num_resources = 1,
- .resource = &gateway7001_flash_resource,
-};
-
-static struct resource gateway7001_uart_resource = {
- .start = IXP4XX_UART2_BASE_PHYS,
- .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
-};
-
-static struct plat_serial8250_port gateway7001_uart_data[] = {
- {
- .mapbase = IXP4XX_UART2_BASE_PHYS,
- .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
- .irq = IRQ_IXP4XX_UART2,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = IXP4XX_UART_XTAL,
- },
- { },
-};
-
-static struct platform_device gateway7001_uart = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = gateway7001_uart_data,
- },
- .num_resources = 1,
- .resource = &gateway7001_uart_resource,
-};
-
-static struct platform_device *gateway7001_devices[] __initdata = {
- &gateway7001_flash,
- &gateway7001_uart
-};
-
-static void __init gateway7001_init(void)
-{
- ixp4xx_sys_init();
-
- gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
- gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
-
- *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
- *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
-
- platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
-}
-
-#ifdef CONFIG_MACH_GATEWAY7001
-MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
- /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
- .map_io = ixp4xx_map_io,
- .init_early = ixp4xx_init_early,
- .init_irq = ixp4xx_init_irq,
- .init_time = ixp4xx_timer_init,
- .atag_offset = 0x100,
- .init_machine = gateway7001_init,
-#if defined(CONFIG_PCI)
- .dma_zone_size = SZ_64M,
-#endif
- .restart = ixp4xx_restart,
-MACHINE_END
-#endif
diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c
deleted file mode 100644
index 07b50dfcc489..000000000000
--- a/arch/arm/mach-ixp4xx/goramo_mlr.c
+++ /dev/null
@@ -1,532 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Goramo MultiLink router platform code
- * Copyright (C) 2006-2009 Krzysztof Halasa <khc@pm.waw.pl>
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/hdlc.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/platform_data/wan_ixp4xx_hss.h>
-#include <linux/serial_8250.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-#include <asm/mach/pci.h>
-#include <asm/system_info.h>
-
-#include "irqs.h"
-
-#define SLOT_ETHA 0x0B /* IDSEL = AD21 */
-#define SLOT_ETHB 0x0C /* IDSEL = AD20 */
-#define SLOT_MPCI 0x0D /* IDSEL = AD19 */
-#define SLOT_NEC 0x0E /* IDSEL = AD18 */
-
-/* GPIO lines */
-#define GPIO_SCL 0
-#define GPIO_SDA 1
-#define GPIO_STR 2
-#define GPIO_IRQ_NEC 3
-#define GPIO_IRQ_ETHA 4
-#define GPIO_IRQ_ETHB 5
-#define GPIO_HSS0_DCD_N 6
-#define GPIO_HSS1_DCD_N 7
-#define GPIO_UART0_DCD 8
-#define GPIO_UART1_DCD 9
-#define GPIO_HSS0_CTS_N 10
-#define GPIO_HSS1_CTS_N 11
-#define GPIO_IRQ_MPCI 12
-#define GPIO_HSS1_RTS_N 13
-#define GPIO_HSS0_RTS_N 14
-/* GPIO15 is not connected */
-
-/* Control outputs from 74HC4094 */
-#define CONTROL_HSS0_CLK_INT 0
-#define CONTROL_HSS1_CLK_INT 1
-#define CONTROL_HSS0_DTR_N 2
-#define CONTROL_HSS1_DTR_N 3
-#define CONTROL_EXT 4
-#define CONTROL_AUTO_RESET 5
-#define CONTROL_PCI_RESET_N 6
-#define CONTROL_EEPROM_WC_N 7
-
-/* offsets from start of flash ROM = 0x50000000 */
-#define CFG_ETH0_ADDRESS 0x40 /* 6 bytes */
-#define CFG_ETH1_ADDRESS 0x46 /* 6 bytes */
-#define CFG_REV 0x4C /* u32 */
-#define CFG_SDRAM_SIZE 0x50 /* u32 */
-#define CFG_SDRAM_CONF 0x54 /* u32 */
-#define CFG_SDRAM_MODE 0x58 /* u32 */
-#define CFG_SDRAM_REFRESH 0x5C /* u32 */
-
-#define CFG_HW_BITS 0x60 /* u32 */
-#define CFG_HW_USB_PORTS 0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
-#define CFG_HW_HAS_PCI_SLOT 0x00000008
-#define CFG_HW_HAS_ETH0 0x00000010
-#define CFG_HW_HAS_ETH1 0x00000020
-#define CFG_HW_HAS_HSS0 0x00000040
-#define CFG_HW_HAS_HSS1 0x00000080
-#define CFG_HW_HAS_UART0 0x00000100
-#define CFG_HW_HAS_UART1 0x00000200
-#define CFG_HW_HAS_EEPROM 0x00000400
-
-#define FLASH_CMD_READ_ARRAY 0xFF
-#define FLASH_CMD_READ_ID 0x90
-#define FLASH_SER_OFF 0x102 /* 0x81 in 16-bit mode */
-
-static u32 hw_bits = 0xFFFFFFFD; /* assume all hardware present */;
-static u8 control_value;
-
-/*
- * FIXME: this is reimplementing I2C bit-bangining. Move this
- * over to using driver/i2c/busses/i2c-gpio.c like all other boards
- * and register proper I2C device(s) on the bus for this. (See
- * other IXP4xx boards for examples.)
- */
-static void set_scl(u8 value)
-{
- gpio_set_value(GPIO_SCL, !!value);
- udelay(3);
-}
-
-static void set_sda(u8 value)
-{
- gpio_set_value(GPIO_SDA, !!value);
- udelay(3);
-}
-
-static void set_str(u8 value)
-{
- gpio_set_value(GPIO_STR, !!value);
- udelay(3);
-}
-
-static inline void set_control(int line, int value)
-{
- if (value)
- control_value |= (1 << line);
- else
- control_value &= ~(1 << line);
-}
-
-
-static void output_control(void)
-{
- int i;
-
- gpio_direction_output(GPIO_SCL, 1);
- gpio_direction_output(GPIO_SDA, 1);
-
- for (i = 0; i < 8; i++) {
- set_scl(0);
- set_sda(control_value & (0x80 >> i)); /* MSB first */
- set_scl(1); /* active edge */
- }
-
- set_str(1);
- set_str(0);
-
- set_scl(0);
- set_sda(1); /* Be ready for START */
- set_scl(1);
-}
-
-
-static void (*set_carrier_cb_tab[2])(void *pdev, int carrier);
-
-static int hss_set_clock(int port, unsigned int clock_type)
-{
- int ctrl_int = port ? CONTROL_HSS1_CLK_INT : CONTROL_HSS0_CLK_INT;
-
- switch (clock_type) {
- case CLOCK_DEFAULT:
- case CLOCK_EXT:
- set_control(ctrl_int, 0);
- output_control();
- return CLOCK_EXT;
-
- case CLOCK_INT:
- set_control(ctrl_int, 1);
- output_control();
- return CLOCK_INT;
-
- default:
- return -EINVAL;
- }
-}
-
-static irqreturn_t hss_dcd_irq(int irq, void *pdev)
-{
- int port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
- int i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
- set_carrier_cb_tab[port](pdev, !i);
- return IRQ_HANDLED;
-}
-
-
-static int hss_open(int port, void *pdev,
- void (*set_carrier_cb)(void *pdev, int carrier))
-{
- int i, irq;
-
- if (!port)
- irq = IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N);
- else
- irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);
-
- i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
- set_carrier_cb(pdev, !i);
-
- set_carrier_cb_tab[!!port] = set_carrier_cb;
-
- if ((i = request_irq(irq, hss_dcd_irq, 0, "IXP4xx HSS", pdev)) != 0) {
- printk(KERN_ERR "ixp4xx_hss: failed to request IRQ%i (%i)\n",
- irq, i);
- return i;
- }
-
- set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);
- output_control();
- gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
- return 0;
-}
-
-static void hss_close(int port, void *pdev)
-{
- free_irq(port ? IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N) :
- IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), pdev);
- set_carrier_cb_tab[!!port] = NULL; /* catch bugs */
-
- set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
- output_control();
- gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
-}
-
-
-/* Flash memory */
-static struct flash_platform_data flash_data = {
- .map_name = "cfi_probe",
- .width = 2,
-};
-
-static struct resource flash_resource = {
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device device_flash = {
- .name = "IXP4XX-Flash",
- .id = 0,
- .dev = { .platform_data = &flash_data },
- .num_resources = 1,
- .resource = &flash_resource,
-};
-
-/* IXP425 2 UART ports */
-static struct resource uart_resources[] = {
- {
- .start = IXP4XX_UART1_BASE_PHYS,
- .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IXP4XX_UART2_BASE_PHYS,
- .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct plat_serial8250_port uart_data[] = {
- {
- .mapbase = IXP4XX_UART1_BASE_PHYS,
- .membase = (char __iomem *)IXP4XX_UART1_BASE_VIRT +
- REG_OFFSET,
- .irq = IRQ_IXP4XX_UART1,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = IXP4XX_UART_XTAL,
- },
- {
- .mapbase = IXP4XX_UART2_BASE_PHYS,
- .membase = (char __iomem *)IXP4XX_UART2_BASE_VIRT +
- REG_OFFSET,
- .irq = IRQ_IXP4XX_UART2,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = IXP4XX_UART_XTAL,
- },
- { },
-};
-
-static struct platform_device device_uarts = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev.platform_data = uart_data,
- .num_resources = 2,
- .resource = uart_resources,
-};
-
-
-/* Built-in 10/100 Ethernet MAC interfaces */
-static struct resource eth_npeb_resources[] = {
- {
- .start = IXP4XX_EthB_BASE_PHYS,
- .end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct resource eth_npec_resources[] = {
- {
- .start = IXP4XX_EthC_BASE_PHYS,
- .end = IXP4XX_EthC_BASE_PHYS + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct eth_plat_info eth_plat[] = {
- {
- .phy = 0,
- .rxq = 3,
- .txreadyq = 32,
- }, {
- .phy = 1,
- .rxq = 4,
- .txreadyq = 33,
- }
-};
-
-static struct platform_device device_eth_tab[] = {
- {
- .name = "ixp4xx_eth",
- .id = IXP4XX_ETH_NPEB,
- .dev.platform_data = eth_plat,
- .num_resources = ARRAY_SIZE(eth_npeb_resources),
- .resource = eth_npeb_resources,
- }, {
- .name = "ixp4xx_eth",
- .id = IXP4XX_ETH_NPEC,
- .dev.platform_data = eth_plat + 1,
- .num_resources = ARRAY_SIZE(eth_npec_resources),
- .resource = eth_npec_resources,
- }
-};
-
-
-/* IXP425 2 synchronous serial ports */
-static struct hss_plat_info hss_plat[] = {
- {
- .set_clock = hss_set_clock,
- .open = hss_open,
- .close = hss_close,
- .txreadyq = 34,
- }, {
- .set_clock = hss_set_clock,
- .open = hss_open,
- .close = hss_close,
- .txreadyq = 35,
- }
-};
-
-static struct platform_device device_hss_tab[] = {
- {
- .name = "ixp4xx_hss",
- .id = 0,
- .dev.platform_data = hss_plat,
- }, {
- .name = "ixp4xx_hss",
- .id = 1,
- .dev.platform_data = hss_plat + 1,
- }
-};
-
-
-static struct platform_device *device_tab[7] __initdata = {
- &device_flash, /* index 0 */
-};
-
-static inline u8 __init flash_readb(u8 __iomem *flash, u32 addr)
-{
-#ifdef __ARMEB__
- return __raw_readb(flash + addr);
-#else
- return __raw_readb(flash + (addr ^ 3));
-#endif
-}
-
-static inline u16 __init flash_readw(u8 __iomem *flash, u32 addr)
-{
-#ifdef __ARMEB__
- return __raw_readw(flash + addr);
-#else
- return __raw_readw(flash + (addr ^ 2));
-#endif
-}
-
-static void __init gmlr_init(void)
-{
- u8 __iomem *flash;
- int i, devices = 1; /* flash */
-
- ixp4xx_sys_init();
-
- if ((flash = ioremap(IXP4XX_EXP_BUS_BASE_PHYS, 0x80)) == NULL)
- printk(KERN_ERR "goramo-mlr: unable to access system"
- " configuration data\n");
- else {
- system_rev = __raw_readl(flash + CFG_REV);
- hw_bits = __raw_readl(flash + CFG_HW_BITS);
-
- for (i = 0; i < ETH_ALEN; i++) {
- eth_plat[0].hwaddr[i] =
- flash_readb(flash, CFG_ETH0_ADDRESS + i);
- eth_plat[1].hwaddr[i] =
- flash_readb(flash, CFG_ETH1_ADDRESS + i);
- }
-
- __raw_writew(FLASH_CMD_READ_ID, flash);
- system_serial_high = flash_readw(flash, FLASH_SER_OFF);
- system_serial_high <<= 16;
- system_serial_high |= flash_readw(flash, FLASH_SER_OFF + 2);
- system_serial_low = flash_readw(flash, FLASH_SER_OFF + 4);
- system_serial_low <<= 16;
- system_serial_low |= flash_readw(flash, FLASH_SER_OFF + 6);
- __raw_writew(FLASH_CMD_READ_ARRAY, flash);
-
- iounmap(flash);
- }
-
- switch (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1)) {
- case CFG_HW_HAS_UART0:
- memset(&uart_data[1], 0, sizeof(uart_data[1]));
- device_uarts.num_resources = 1;
- break;
-
- case CFG_HW_HAS_UART1:
- device_uarts.dev.platform_data = &uart_data[1];
- device_uarts.resource = &uart_resources[1];
- device_uarts.num_resources = 1;
- break;
- }
- if (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1))
- device_tab[devices++] = &device_uarts; /* max index 1 */
-
- if (hw_bits & CFG_HW_HAS_ETH0)
- device_tab[devices++] = &device_eth_tab[0]; /* max index 2 */
- if (hw_bits & CFG_HW_HAS_ETH1)
- device_tab[devices++] = &device_eth_tab[1]; /* max index 3 */
-
- if (hw_bits & CFG_HW_HAS_HSS0)
- device_tab[devices++] = &device_hss_tab[0]; /* max index 4 */
- if (hw_bits & CFG_HW_HAS_HSS1)
- device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
-
- hss_plat[0].timer_freq = ixp4xx_timer_freq;
- hss_plat[1].timer_freq = ixp4xx_timer_freq;
-
- gpio_request(GPIO_SCL, "SCL/clock");
- gpio_request(GPIO_SDA, "SDA/data");
- gpio_request(GPIO_STR, "strobe");
- gpio_request(GPIO_HSS0_RTS_N, "HSS0 RTS");
- gpio_request(GPIO_HSS1_RTS_N, "HSS1 RTS");
- gpio_request(GPIO_HSS0_DCD_N, "HSS0 DCD");
- gpio_request(GPIO_HSS1_DCD_N, "HSS1 DCD");
-
- gpio_direction_output(GPIO_SCL, 1);
- gpio_direction_output(GPIO_SDA, 1);
- gpio_direction_output(GPIO_STR, 0);
- gpio_direction_output(GPIO_HSS0_RTS_N, 1);
- gpio_direction_output(GPIO_HSS1_RTS_N, 1);
- gpio_direction_input(GPIO_HSS0_DCD_N);
- gpio_direction_input(GPIO_HSS1_DCD_N);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
-
- set_control(CONTROL_HSS0_DTR_N, 1);
- set_control(CONTROL_HSS1_DTR_N, 1);
- set_control(CONTROL_EEPROM_WC_N, 1);
- set_control(CONTROL_PCI_RESET_N, 1);
- output_control();
-
- msleep(1); /* Wait for PCI devices to initialize */
-
- flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
- flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
-
- platform_add_devices(device_tab, devices);
-}
-
-
-#ifdef CONFIG_PCI
-static void __init gmlr_pci_preinit(void)
-{
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);
- ixp4xx_pci_preinit();
-}
-
-static void __init gmlr_pci_postinit(void)
-{
- if ((hw_bits & CFG_HW_USB_PORTS) >= 2 &&
- (hw_bits & CFG_HW_USB_PORTS) < 5) {
- /* need to adjust number of USB ports on NEC chip */
- u32 value, addr = BIT(32 - SLOT_NEC) | 0xE0;
- if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
- value &= ~7;
- value |= (hw_bits & CFG_HW_USB_PORTS);
- ixp4xx_pci_write(addr, NP_CMD_CONFIGWRITE, value);
- }
- }
-}
-
-static int __init gmlr_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- switch(slot) {
- case SLOT_ETHA: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA);
- case SLOT_ETHB: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB);
- case SLOT_NEC: return IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC);
- default: return IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI);
- }
-}
-
-static struct hw_pci gmlr_hw_pci __initdata = {
- .nr_controllers = 1,
- .ops = &ixp4xx_ops,
- .preinit = gmlr_pci_preinit,
- .postinit = gmlr_pci_postinit,
- .setup = ixp4xx_setup,
- .map_irq = gmlr_map_irq,
-};
-
-static int __init gmlr_pci_init(void)
-{
- if (machine_is_goramo_mlr() &&
- (hw_bits & (CFG_HW_USB_PORTS | CFG_HW_HAS_PCI_SLOT)))
- pci_common_init(&gmlr_hw_pci);
- return 0;
-}
-
-subsys_initcall(gmlr_pci_init);
-#endif /* CONFIG_PCI */
-
-
-MACHINE_START(GORAMO_MLR, "MultiLink")
- /* Maintainer: Krzysztof Halasa */
- .map_io = ixp4xx_map_io,
- .init_early = ixp4xx_init_early,
- .init_irq = ixp4xx_init_irq,
- .init_time = ixp4xx_timer_init,
- .atag_offset = 0x100,
- .init_machine = gmlr_init,
-#if defined(CONFIG_PCI)
- .dma_zone_size = SZ_64M,
-#endif
- .restart = ixp4xx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h
deleted file mode 100644
index b2b7301ce503..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/hardware.h
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-/*
- * Hardware definitions for IXP4xx based systems
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#define __ASM_ARCH_HARDWARE_H__
-
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-#define PCIBIOS_MAX_MEM 0x4FFFFFFF
-#else
-#define PCIBIOS_MAX_MEM 0x4BFFFFFF
-#endif
-
-/* Register locations and bits */
-#include "ixp4xx-regs.h"
-
-#ifndef __ASSEMBLER__
-#include <linux/soc/ixp4xx/cpu.h>
-#endif
-
-/* Platform helper functions and definitions */
-#include "platform.h"
-
-#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
deleted file mode 100644
index 014cf6dcaf8b..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/io.h
+++ /dev/null
@@ -1,545 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/io.h
- *
- * Author: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright (C) 2002-2005 MontaVista Software, Inc.
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#include <linux/bitops.h>
-
-#include <mach/hardware.h>
-
-extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
-extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
-
-
-/*
- * IXP4xx provides two methods of accessing PCI memory space:
- *
- * 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
- * To access PCI via this space, we simply ioremap() the BAR
- * into the kernel and we can use the standard read[bwl]/write[bwl]
- * macros. This is the preffered method due to speed but it
- * limits the system to just 64MB of PCI memory. This can be
- * problematic if using video cards and other memory-heavy targets.
- *
- * 2) If > 64MB of memory space is required, the IXP4xx can use indirect
- * registers to access the whole 4 GB of PCI memory space (as we do below
- * for I/O transactions). This allows currently for up to 1 GB (0x10000000
- * to 0x4FFFFFFF) of memory on the bus. The disadvantage of this is that
- * every PCI access requires three local register accesses plus a spinlock,
- * but in some cases the performance hit is acceptable. In addition, you
- * cannot mmap() PCI devices in this case.
- */
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-
-/*
- * In the case of using indirect PCI, we simply return the actual PCI
- * address and our read/write implementation use that to drive the
- * access registers. If something outside of PCI is ioremap'd, we
- * fallback to the default.
- */
-
-extern unsigned long pcibios_min_mem;
-static inline int is_pci_memory(u32 addr)
-{
- return (addr >= pcibios_min_mem) && (addr <= 0x4FFFFFFF);
-}
-
-#define writeb(v, p) __indirect_writeb(v, p)
-#define writew(v, p) __indirect_writew(v, p)
-#define writel(v, p) __indirect_writel(v, p)
-
-#define writeb_relaxed(v, p) __indirect_writeb(v, p)
-#define writew_relaxed(v, p) __indirect_writew(v, p)
-#define writel_relaxed(v, p) __indirect_writel(v, p)
-
-#define writesb(p, v, l) __indirect_writesb(p, v, l)
-#define writesw(p, v, l) __indirect_writesw(p, v, l)
-#define writesl(p, v, l) __indirect_writesl(p, v, l)
-
-#define readb(p) __indirect_readb(p)
-#define readw(p) __indirect_readw(p)
-#define readl(p) __indirect_readl(p)
-
-#define readb_relaxed(p) __indirect_readb(p)
-#define readw_relaxed(p) __indirect_readw(p)
-#define readl_relaxed(p) __indirect_readl(p)
-
-#define readsb(p, v, l) __indirect_readsb(p, v, l)
-#define readsw(p, v, l) __indirect_readsw(p, v, l)
-#define readsl(p, v, l) __indirect_readsl(p, v, l)
-
-static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
-{
- u32 addr = (u32)p;
- u32 n, byte_enables, data;
-
- if (!is_pci_memory(addr)) {
- __raw_writeb(value, p);
- return;
- }
-
- n = addr % 4;
- byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
- data = value << (8*n);
- ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
-}
-
-static inline void __indirect_writesb(volatile void __iomem *bus_addr,
- const void *p, int count)
-{
- const u8 *vaddr = p;
-
- while (count--)
- writeb(*vaddr++, bus_addr);
-}
-
-static inline void __indirect_writew(u16 value, volatile void __iomem *p)
-{
- u32 addr = (u32)p;
- u32 n, byte_enables, data;
-
- if (!is_pci_memory(addr)) {
- __raw_writew(value, p);
- return;
- }
-
- n = addr % 4;
- byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
- data = value << (8*n);
- ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
-}
-
-static inline void __indirect_writesw(volatile void __iomem *bus_addr,
- const void *p, int count)
-{
- const u16 *vaddr = p;
-
- while (count--)
- writew(*vaddr++, bus_addr);
-}
-
-static inline void __indirect_writel(u32 value, volatile void __iomem *p)
-{
- u32 addr = (__force u32)p;
-
- if (!is_pci_memory(addr)) {
- __raw_writel(value, p);
- return;
- }
-
- ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
-}
-
-static inline void __indirect_writesl(volatile void __iomem *bus_addr,
- const void *p, int count)
-{
- const u32 *vaddr = p;
- while (count--)
- writel(*vaddr++, bus_addr);
-}
-
-static inline u8 __indirect_readb(const volatile void __iomem *p)
-{
- u32 addr = (u32)p;
- u32 n, byte_enables, data;
-
- if (!is_pci_memory(addr))
- return __raw_readb(p);
-
- n = addr % 4;
- byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
- return 0xff;
-
- return data >> (8*n);
-}
-
-static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
- void *p, u32 count)
-{
- u8 *vaddr = p;
-
- while (count--)
- *vaddr++ = readb(bus_addr);
-}
-
-static inline u16 __indirect_readw(const volatile void __iomem *p)
-{
- u32 addr = (u32)p;
- u32 n, byte_enables, data;
-
- if (!is_pci_memory(addr))
- return __raw_readw(p);
-
- n = addr % 4;
- byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
- return 0xffff;
-
- return data>>(8*n);
-}
-
-static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
- void *p, u32 count)
-{
- u16 *vaddr = p;
-
- while (count--)
- *vaddr++ = readw(bus_addr);
-}
-
-static inline u32 __indirect_readl(const volatile void __iomem *p)
-{
- u32 addr = (__force u32)p;
- u32 data;
-
- if (!is_pci_memory(addr))
- return __raw_readl(p);
-
- if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
- return 0xffffffff;
-
- return data;
-}
-
-static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
- void *p, u32 count)
-{
- u32 *vaddr = p;
-
- while (count--)
- *vaddr++ = readl(bus_addr);
-}
-
-
-/*
- * We can use the built-in functions b/c they end up calling writeb/readb
- */
-#define memset_io(c,v,l) _memset_io((c),(v),(l))
-#define memcpy_fromio(a,c,l) _memcpy_fromio((a),(c),(l))
-#define memcpy_toio(c,a,l) _memcpy_toio((c),(a),(l))
-
-#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
-
-#ifndef CONFIG_PCI
-
-#define __io(v) __typesafe_io(v)
-
-#else
-
-/*
- * IXP4xx does not have a transparent cpu -> PCI I/O translation
- * window. Instead, it has a set of registers that must be tweaked
- * with the proper byte lanes, command types, and address for the
- * transaction. This means that we need to override the default
- * I/O functions.
- */
-
-#define outb outb
-static inline void outb(u8 value, u32 addr)
-{
- u32 n, byte_enables, data;
- n = addr % 4;
- byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
- data = value << (8*n);
- ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
-}
-
-#define outsb outsb
-static inline void outsb(u32 io_addr, const void *p, u32 count)
-{
- const u8 *vaddr = p;
-
- while (count--)
- outb(*vaddr++, io_addr);
-}
-
-#define outw outw
-static inline void outw(u16 value, u32 addr)
-{
- u32 n, byte_enables, data;
- n = addr % 4;
- byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
- data = value << (8*n);
- ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
-}
-
-#define outsw outsw
-static inline void outsw(u32 io_addr, const void *p, u32 count)
-{
- const u16 *vaddr = p;
- while (count--)
- outw(cpu_to_le16(*vaddr++), io_addr);
-}
-
-#define outl outl
-static inline void outl(u32 value, u32 addr)
-{
- ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
-}
-
-#define outsl outsl
-static inline void outsl(u32 io_addr, const void *p, u32 count)
-{
- const u32 *vaddr = p;
- while (count--)
- outl(cpu_to_le32(*vaddr++), io_addr);
-}
-
-#define inb inb
-static inline u8 inb(u32 addr)
-{
- u32 n, byte_enables, data;
- n = addr % 4;
- byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
- return 0xff;
-
- return data >> (8*n);
-}
-
-#define insb insb
-static inline void insb(u32 io_addr, void *p, u32 count)
-{
- u8 *vaddr = p;
- while (count--)
- *vaddr++ = inb(io_addr);
-}
-
-#define inw inw
-static inline u16 inw(u32 addr)
-{
- u32 n, byte_enables, data;
- n = addr % 4;
- byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
- if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
- return 0xffff;
-
- return data>>(8*n);
-}
-
-#define insw insw
-static inline void insw(u32 io_addr, void *p, u32 count)
-{
- u16 *vaddr = p;
- while (count--)
- *vaddr++ = le16_to_cpu(inw(io_addr));
-}
-
-#define inl inl
-static inline u32 inl(u32 addr)
-{
- u32 data;
- if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
- return 0xffffffff;
-
- return data;
-}
-
-#define insl insl
-static inline void insl(u32 io_addr, void *p, u32 count)
-{
- u32 *vaddr = p;
- while (count--)
- *vaddr++ = le32_to_cpu(inl(io_addr));
-}
-
-#define PIO_OFFSET 0x10000UL
-#define PIO_MASK 0x0ffffUL
-
-#define __is_io_address(p) (((unsigned long)p >= PIO_OFFSET) && \
- ((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
-
-#define ioread8(p) ioread8(p)
-static inline u8 ioread8(const void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- return (unsigned int)inb(port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- return (unsigned int)__raw_readb(addr);
-#else
- return (unsigned int)__indirect_readb(addr);
-#endif
-}
-
-#define ioread8_rep(p, v, c) ioread8_rep(p, v, c)
-static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- insb(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_readsb(addr, vaddr, count);
-#else
- __indirect_readsb(addr, vaddr, count);
-#endif
-}
-
-#define ioread16(p) ioread16(p)
-static inline u16 ioread16(const void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- return (unsigned int)inw(port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- return le16_to_cpu((__force __le16)__raw_readw(addr));
-#else
- return (unsigned int)__indirect_readw(addr);
-#endif
-}
-
-#define ioread16_rep(p, v, c) ioread16_rep(p, v, c)
-static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- insw(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_readsw(addr, vaddr, count);
-#else
- __indirect_readsw(addr, vaddr, count);
-#endif
-}
-
-#define ioread32(p) ioread32(p)
-static inline u32 ioread32(const void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- return (unsigned int)inl(port & PIO_MASK);
- else {
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- return le32_to_cpu((__force __le32)__raw_readl(addr));
-#else
- return (unsigned int)__indirect_readl(addr);
-#endif
- }
-}
-
-#define ioread32_rep(p, v, c) ioread32_rep(p, v, c)
-static inline void ioread32_rep(const void __iomem *addr, void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- insl(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_readsl(addr, vaddr, count);
-#else
- __indirect_readsl(addr, vaddr, count);
-#endif
-}
-
-#define iowrite8(v, p) iowrite8(v, p)
-static inline void iowrite8(u8 value, void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outb(value, port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writeb(value, addr);
-#else
- __indirect_writeb(value, addr);
-#endif
-}
-
-#define iowrite8_rep(p, v, c) iowrite8_rep(p, v, c)
-static inline void iowrite8_rep(void __iomem *addr, const void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outsb(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writesb(addr, vaddr, count);
-#else
- __indirect_writesb(addr, vaddr, count);
-#endif
-}
-
-#define iowrite16(v, p) iowrite16(v, p)
-static inline void iowrite16(u16 value, void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outw(value, port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writew(cpu_to_le16(value), addr);
-#else
- __indirect_writew(value, addr);
-#endif
-}
-
-#define iowrite16_rep(p, v, c) iowrite16_rep(p, v, c)
-static inline void iowrite16_rep(void __iomem *addr, const void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outsw(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writesw(addr, vaddr, count);
-#else
- __indirect_writesw(addr, vaddr, count);
-#endif
-}
-
-#define iowrite32(v, p) iowrite32(v, p)
-static inline void iowrite32(u32 value, void __iomem *addr)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outl(value, port & PIO_MASK);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writel((u32 __force)cpu_to_le32(value), addr);
-#else
- __indirect_writel(value, addr);
-#endif
-}
-
-#define iowrite32_rep(p, v, c) iowrite32_rep(p, v, c)
-static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
- u32 count)
-{
- unsigned long port = (unsigned long __force)addr;
- if (__is_io_address(port))
- outsl(port & PIO_MASK, vaddr, count);
- else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
- __raw_writesl(addr, vaddr, count);
-#else
- __indirect_writesl(addr, vaddr, count);
-#endif
-}
-
-#define ioport_map(port, nr) ioport_map(port, nr)
-static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
-{
- return ((void __iomem*)((port) + PIO_OFFSET));
-}
-#define ioport_unmap(addr) ioport_unmap(addr)
-static inline void ioport_unmap(void __iomem *addr)
-{
-}
-#endif /* CONFIG_PCI */
-
-#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
deleted file mode 100644
index 74e63d4531aa..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
- *
- * Register definitions for IXP4xx chipset. This file contains
- * register location and bit definitions only. Platform specific
- * definitions and helper function declarations are in platform.h
- * and machine-name.h.
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-#ifndef _ASM_ARM_IXP4XX_H_
-#define _ASM_ARM_IXP4XX_H_
-
-/*
- * IXP4xx Linux Memory Map:
- *
- * Phy Size Virt Description
- * =========================================================================
- *
- * 0x00000000 0x10000000(max) PAGE_OFFSET System RAM
- *
- * 0x48000000 0x04000000 ioremap'd PCI Memory Space
- *
- * 0x50000000 0x10000000 ioremap'd EXP BUS
- *
- * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals
- *
- * 0xC0000000 0x00001000 0xFEF13000 PCI CFG
- *
- * 0xC4000000 0x00001000 0xFEF14000 EXP CFG
- *
- * 0x60000000 0x00004000 0xFEF15000 QMgr
- */
-
-/*
- * Queue Manager
- */
-#define IXP4XX_QMGR_BASE_PHYS 0x60000000
-
-/*
- * Peripheral space, including debug UART. Must be section-aligned so that
- * it can be used with the low-level debug code.
- */
-#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000
-#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEC00000)
-#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000
-
-/*
- * PCI Config registers
- */
-#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000
-#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEC13000)
-#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000
-
-/*
- * Expansion BUS Configuration registers
- */
-#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000
-#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEC14000
-#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000
-
-#define IXP4XX_EXP_CS0_OFFSET 0x00
-#define IXP4XX_EXP_CS1_OFFSET 0x04
-#define IXP4XX_EXP_CS2_OFFSET 0x08
-#define IXP4XX_EXP_CS3_OFFSET 0x0C
-#define IXP4XX_EXP_CS4_OFFSET 0x10
-#define IXP4XX_EXP_CS5_OFFSET 0x14
-#define IXP4XX_EXP_CS6_OFFSET 0x18
-#define IXP4XX_EXP_CS7_OFFSET 0x1C
-#define IXP4XX_EXP_CFG0_OFFSET 0x20
-#define IXP4XX_EXP_CFG1_OFFSET 0x24
-#define IXP4XX_EXP_CFG2_OFFSET 0x28
-#define IXP4XX_EXP_CFG3_OFFSET 0x2C
-
-/*
- * Expansion Bus Controller registers.
- */
-#define IXP4XX_EXP_REG(x) ((volatile u32 __iomem *)(IXP4XX_EXP_CFG_BASE_VIRT+(x)))
-
-#define IXP4XX_EXP_CS0 IXP4XX_EXP_REG(IXP4XX_EXP_CS0_OFFSET)
-#define IXP4XX_EXP_CS1 IXP4XX_EXP_REG(IXP4XX_EXP_CS1_OFFSET)
-#define IXP4XX_EXP_CS2 IXP4XX_EXP_REG(IXP4XX_EXP_CS2_OFFSET)
-#define IXP4XX_EXP_CS3 IXP4XX_EXP_REG(IXP4XX_EXP_CS3_OFFSET)
-#define IXP4XX_EXP_CS4 IXP4XX_EXP_REG(IXP4XX_EXP_CS4_OFFSET)
-#define IXP4XX_EXP_CS5 IXP4XX_EXP_REG(IXP4XX_EXP_CS5_OFFSET)
-#define IXP4XX_EXP_CS6 IXP4XX_EXP_REG(IXP4XX_EXP_CS6_OFFSET)
-#define IXP4XX_EXP_CS7 IXP4XX_EXP_REG(IXP4XX_EXP_CS7_OFFSET)
-
-#define IXP4XX_EXP_CFG0 IXP4XX_EXP_REG(IXP4XX_EXP_CFG0_OFFSET)
-#define IXP4XX_EXP_CFG1 IXP4XX_EXP_REG(IXP4XX_EXP_CFG1_OFFSET)
-#define IXP4XX_EXP_CFG2 IXP4XX_EXP_REG(IXP4XX_EXP_CFG2_OFFSET)
-#define IXP4XX_EXP_CFG3 IXP4XX_EXP_REG(IXP4XX_EXP_CFG3_OFFSET)
-
-
-/*
- * Peripheral Space Register Region Base Addresses
- */
-#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
-#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
-#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
-#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
-#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
-#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
-#define IXP4XX_NPEA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
-#define IXP4XX_NPEB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
-#define IXP4XX_NPEC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
-#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
-#define IXP4XX_EthC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
-#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
-/* ixp46X only */
-#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
-#define IXP4XX_EthB1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
-#define IXP4XX_EthB2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
-#define IXP4XX_EthB3_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
-#define IXP4XX_TIMESYNC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
-#define IXP4XX_I2C_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
-#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
-
-
-/* The UART is explicitly put in the beginning of fixmap */
-#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
-#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
-#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
-#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
-#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
-#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
-#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
-#define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
-#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
-/* ixp46X only */
-#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
-#define IXP4XX_EthB1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
-#define IXP4XX_EthB2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
-#define IXP4XX_EthB3_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
-#define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
-#define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
-#define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
-
-/*
- * Constants to make it easy to access Timer Control/Status registers
- */
-#define IXP4XX_OSTS_OFFSET 0x00 /* Continious TimeStamp */
-#define IXP4XX_OST1_OFFSET 0x04 /* Timer 1 Timestamp */
-#define IXP4XX_OSRT1_OFFSET 0x08 /* Timer 1 Reload */
-#define IXP4XX_OST2_OFFSET 0x0C /* Timer 2 Timestamp */
-#define IXP4XX_OSRT2_OFFSET 0x10 /* Timer 2 Reload */
-#define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */
-#define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */
-#define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */
-#define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */
-
-/*
- * Operating System Timer Register Definitions.
- */
-
-#define IXP4XX_TIMER_REG(x) ((volatile u32 *)(IXP4XX_TIMER_BASE_VIRT+(x)))
-
-#define IXP4XX_OSTS IXP4XX_TIMER_REG(IXP4XX_OSTS_OFFSET)
-#define IXP4XX_OST1 IXP4XX_TIMER_REG(IXP4XX_OST1_OFFSET)
-#define IXP4XX_OSRT1 IXP4XX_TIMER_REG(IXP4XX_OSRT1_OFFSET)
-#define IXP4XX_OST2 IXP4XX_TIMER_REG(IXP4XX_OST2_OFFSET)
-#define IXP4XX_OSRT2 IXP4XX_TIMER_REG(IXP4XX_OSRT2_OFFSET)
-#define IXP4XX_OSWT IXP4XX_TIMER_REG(IXP4XX_OSWT_OFFSET)
-#define IXP4XX_OSWE IXP4XX_TIMER_REG(IXP4XX_OSWE_OFFSET)
-#define IXP4XX_OSWK IXP4XX_TIMER_REG(IXP4XX_OSWK_OFFSET)
-#define IXP4XX_OSST IXP4XX_TIMER_REG(IXP4XX_OSST_OFFSET)
-
-/*
- * Timer register values and bit definitions
- */
-#define IXP4XX_OST_ENABLE 0x00000001
-#define IXP4XX_OST_ONE_SHOT 0x00000002
-/* Low order bits of reload value ignored */
-#define IXP4XX_OST_RELOAD_MASK 0x00000003
-#define IXP4XX_OST_DISABLED 0x00000000
-#define IXP4XX_OSST_TIMER_1_PEND 0x00000001
-#define IXP4XX_OSST_TIMER_2_PEND 0x00000002
-#define IXP4XX_OSST_TIMER_TS_PEND 0x00000004
-#define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008
-#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
-
-#define IXP4XX_WDT_KEY 0x0000482E
-
-#define IXP4XX_WDT_RESET_ENABLE 0x00000001
-#define IXP4XX_WDT_IRQ_ENABLE 0x00000002
-#define IXP4XX_WDT_COUNT_ENABLE 0x00000004
-
-
-/*
- * Constants to make it easy to access PCI Control/Status registers
- */
-#define PCI_NP_AD_OFFSET 0x00
-#define PCI_NP_CBE_OFFSET 0x04
-#define PCI_NP_WDATA_OFFSET 0x08
-#define PCI_NP_RDATA_OFFSET 0x0c
-#define PCI_CRP_AD_CBE_OFFSET 0x10
-#define PCI_CRP_WDATA_OFFSET 0x14
-#define PCI_CRP_RDATA_OFFSET 0x18
-#define PCI_CSR_OFFSET 0x1c
-#define PCI_ISR_OFFSET 0x20
-#define PCI_INTEN_OFFSET 0x24
-#define PCI_DMACTRL_OFFSET 0x28
-#define PCI_AHBMEMBASE_OFFSET 0x2c
-#define PCI_AHBIOBASE_OFFSET 0x30
-#define PCI_PCIMEMBASE_OFFSET 0x34
-#define PCI_AHBDOORBELL_OFFSET 0x38
-#define PCI_PCIDOORBELL_OFFSET 0x3C
-#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
-#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
-#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
-#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
-#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
-#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
-
-/*
- * PCI Control/Status Registers
- */
-#define _IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE_VIRT+(x)))
-
-#define PCI_NP_AD _IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
-#define PCI_NP_CBE _IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
-#define PCI_NP_WDATA _IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
-#define PCI_NP_RDATA _IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
-#define PCI_CRP_AD_CBE _IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
-#define PCI_CRP_WDATA _IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
-#define PCI_CRP_RDATA _IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
-#define PCI_CSR _IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
-#define PCI_ISR _IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
-#define PCI_INTEN _IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
-#define PCI_DMACTRL _IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
-#define PCI_AHBMEMBASE _IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
-#define PCI_AHBIOBASE _IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
-#define PCI_PCIMEMBASE _IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
-#define PCI_AHBDOORBELL _IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
-#define PCI_PCIDOORBELL _IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
-#define PCI_ATPDMA0_AHBADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
-#define PCI_ATPDMA0_PCIADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
-#define PCI_ATPDMA0_LENADDR _IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
-#define PCI_ATPDMA1_AHBADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
-#define PCI_ATPDMA1_PCIADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
-#define PCI_ATPDMA1_LENADDR _IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
-
-/*
- * PCI register values and bit definitions
- */
-
-/* CSR bit definitions */
-#define PCI_CSR_HOST 0x00000001
-#define PCI_CSR_ARBEN 0x00000002
-#define PCI_CSR_ADS 0x00000004
-#define PCI_CSR_PDS 0x00000008
-#define PCI_CSR_ABE 0x00000010
-#define PCI_CSR_DBT 0x00000020
-#define PCI_CSR_ASE 0x00000100
-#define PCI_CSR_IC 0x00008000
-
-/* ISR (Interrupt status) Register bit definitions */
-#define PCI_ISR_PSE 0x00000001
-#define PCI_ISR_PFE 0x00000002
-#define PCI_ISR_PPE 0x00000004
-#define PCI_ISR_AHBE 0x00000008
-#define PCI_ISR_APDC 0x00000010
-#define PCI_ISR_PADC 0x00000020
-#define PCI_ISR_ADB 0x00000040
-#define PCI_ISR_PDB 0x00000080
-
-/* INTEN (Interrupt Enable) Register bit definitions */
-#define PCI_INTEN_PSE 0x00000001
-#define PCI_INTEN_PFE 0x00000002
-#define PCI_INTEN_PPE 0x00000004
-#define PCI_INTEN_AHBE 0x00000008
-#define PCI_INTEN_APDC 0x00000010
-#define PCI_INTEN_PADC 0x00000020
-#define PCI_INTEN_ADB 0x00000040
-#define PCI_INTEN_PDB 0x00000080
-
-/*
- * Shift value for byte enable on NP cmd/byte enable register
- */
-#define IXP4XX_PCI_NP_CBE_BESL 4
-
-/*
- * PCI commands supported by NP access unit
- */
-#define NP_CMD_IOREAD 0x2
-#define NP_CMD_IOWRITE 0x3
-#define NP_CMD_CONFIGREAD 0xa
-#define NP_CMD_CONFIGWRITE 0xb
-#define NP_CMD_MEMREAD 0x6
-#define NP_CMD_MEMWRITE 0x7
-
-/*
- * Constants for CRP access into local config space
- */
-#define CRP_AD_CBE_BESL 20
-#define CRP_AD_CBE_WRITE 0x00010000
-
-#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
-
-#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
deleted file mode 100644
index d8b4df96db08..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/platform.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-ixp4xx/include/mach/platform.h
- *
- * Constants and functions that are useful to IXP4xx platform-specific code
- * and device drivers.
- *
- * Copyright (C) 2004 MontaVista Software, Inc.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#ifndef __ASSEMBLY__
-
-#include <linux/reboot.h>
-#include <linux/platform_data/eth_ixp4xx.h>
-
-#include <asm/types.h>
-
-#ifndef __ARMEB__
-#define REG_OFFSET 0
-#else
-#define REG_OFFSET 3
-#endif
-
-/*
- * Expansion bus memory regions
- */
-#define IXP4XX_EXP_BUS_BASE_PHYS (0x50000000)
-
-/*
- * The expansion bus on the IXP4xx can be configured for either 16 or
- * 32MB windows and the CS offset for each region changes based on the
- * current configuration. This means that we cannot simply hardcode
- * each offset. ixp4xx_sys_init() looks at the expansion bus configuration
- * as setup by the bootloader to determine our window size.
- */
-extern unsigned long ixp4xx_exp_bus_size;
-
-#define IXP4XX_EXP_BUS_BASE(region)\
- (IXP4XX_EXP_BUS_BASE_PHYS + ((region) * ixp4xx_exp_bus_size))
-
-#define IXP4XX_EXP_BUS_END(region)\
- (IXP4XX_EXP_BUS_BASE(region) + ixp4xx_exp_bus_size - 1)
-
-/* Those macros can be used to adjust timing and configure
- * other features for each region.
- */
-
-#define IXP4XX_EXP_BUS_RECOVERY_T(x) (((x) & 0x0f) << 16)
-#define IXP4XX_EXP_BUS_HOLD_T(x) (((x) & 0x03) << 20)
-#define IXP4XX_EXP_BUS_STROBE_T(x) (((x) & 0x0f) << 22)
-#define IXP4XX_EXP_BUS_SETUP_T(x) (((x) & 0x03) << 26)
-#define IXP4XX_EXP_BUS_ADDR_T(x) (((x) & 0x03) << 28)
-#define IXP4XX_EXP_BUS_SIZE(x) (((x) & 0x0f) << 10)
-#define IXP4XX_EXP_BUS_CYCLES(x) (((x) & 0x03) << 14)
-
-#define IXP4XX_EXP_BUS_CS_EN (1L << 31)
-#define IXP4XX_EXP_BUS_BYTE_RD16 (1L << 6)
-#define IXP4XX_EXP_BUS_HRDY_POL (1L << 5)
-#define IXP4XX_EXP_BUS_MUX_EN (1L << 4)
-#define IXP4XX_EXP_BUS_SPLT_EN (1L << 3)
-#define IXP4XX_EXP_BUS_WR_EN (1L << 1)
-#define IXP4XX_EXP_BUS_BYTE_EN (1L << 0)
-
-#define IXP4XX_EXP_BUS_CYCLES_INTEL 0x00
-#define IXP4XX_EXP_BUS_CYCLES_MOTOROLA 0x01
-#define IXP4XX_EXP_BUS_CYCLES_HPI 0x02
-
-#define IXP4XX_FLASH_WRITABLE (0x2)
-#define IXP4XX_FLASH_DEFAULT (0xbcd23c40)
-#define IXP4XX_FLASH_WRITE (0xbcd23c42)
-
-/*
- * Clock Speed Definitions.
- */
-#define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66MHzi APB BUS */
-#define IXP4XX_UART_XTAL 14745600
-
-/*
- * Frequency of clock used for primary clocksource
- */
-extern unsigned long ixp4xx_timer_freq;
-
-/*
- * Functions used by platform-level setup code
- */
-extern void ixp4xx_map_io(void);
-extern void ixp4xx_init_early(void);
-extern void ixp4xx_init_irq(void);
-extern void ixp4xx_sys_init(void);
-extern void ixp4xx_timer_init(void);
-extern void ixp4xx_restart(enum reboot_mode, const char *);
-extern void ixp4xx_pci_preinit(void);
-struct pci_sys_data;
-extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
-extern struct pci_ops ixp4xx_ops;
-
-#endif // __ASSEMBLY__
-
diff --git a/arch/arm/mach-ixp4xx/include/mach/udc.h b/arch/arm/mach-ixp4xx/include/mach/udc.h
deleted file mode 100644
index 7bd8b96c8843..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/udc.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/udc.h
- *
- */
-#include <linux/platform_data/pxa2xx_udc.h>
-
-extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
-
diff --git a/arch/arm/mach-ixp4xx/include/mach/uncompress.h b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
index 9e08b270cfc7..09e7663e6a55 100644
--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h
+++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
@@ -9,10 +9,12 @@
#ifndef _ARCH_UNCOMPRESS_H_
#define _ARCH_UNCOMPRESS_H_
-#include "ixp4xx-regs.h"
#include <asm/mach-types.h>
#include <linux/serial_reg.h>
+#define IXP4XX_UART1_BASE_PHYS 0xc8000000
+#define IXP4XX_UART2_BASE_PHYS 0xc8001000
+
#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
volatile u32* uart_base;
diff --git a/arch/arm/mach-ixp4xx/irqs.h b/arch/arm/mach-ixp4xx/irqs.h
deleted file mode 100644
index a3e8d6408c56..000000000000
--- a/arch/arm/mach-ixp4xx/irqs.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/irqs.h
- *
- * IRQ definitions for IXP4XX based systems
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003 MontaVista Software, Inc.
- */
-
-#ifndef _ARCH_IXP4XX_IRQS_H_
-#define _ARCH_IXP4XX_IRQS_H_
-
-#define IRQ_IXP4XX_BASE 16
-
-#define IRQ_IXP4XX_NPEA (IRQ_IXP4XX_BASE + 0)
-#define IRQ_IXP4XX_NPEB (IRQ_IXP4XX_BASE + 1)
-#define IRQ_IXP4XX_NPEC (IRQ_IXP4XX_BASE + 2)
-#define IRQ_IXP4XX_QM1 (IRQ_IXP4XX_BASE + 3)
-#define IRQ_IXP4XX_QM2 (IRQ_IXP4XX_BASE + 4)
-#define IRQ_IXP4XX_TIMER1 (IRQ_IXP4XX_BASE + 5)
-#define IRQ_IXP4XX_GPIO0 (IRQ_IXP4XX_BASE + 6)
-#define IRQ_IXP4XX_GPIO1 (IRQ_IXP4XX_BASE + 7)
-#define IRQ_IXP4XX_PCI_INT (IRQ_IXP4XX_BASE + 8)
-#define IRQ_IXP4XX_PCI_DMA1 (IRQ_IXP4XX_BASE + 9)
-#define IRQ_IXP4XX_PCI_DMA2 (IRQ_IXP4XX_BASE + 10)
-#define IRQ_IXP4XX_TIMER2 (IRQ_IXP4XX_BASE + 11)
-#define IRQ_IXP4XX_USB (IRQ_IXP4XX_BASE + 12)
-#define IRQ_IXP4XX_UART2 (IRQ_IXP4XX_BASE + 13)
-#define IRQ_IXP4XX_TIMESTAMP (IRQ_IXP4XX_BASE + 14)
-#define IRQ_IXP4XX_UART1 (IRQ_IXP4XX_BASE + 15)
-#define IRQ_IXP4XX_WDOG (IRQ_IXP4XX_BASE + 16)
-#define IRQ_IXP4XX_AHB_PMU (IRQ_IXP4XX_BASE + 17)
-#define IRQ_IXP4XX_XSCALE_PMU (IRQ_IXP4XX_BASE + 18)
-#define IRQ_IXP4XX_GPIO2 (IRQ_IXP4XX_BASE + 19)
-#define IRQ_IXP4XX_GPIO3 (IRQ_IXP4XX_BASE + 20)
-#define IRQ_IXP4XX_GPIO4 (IRQ_IXP4XX_BASE + 21)
-#define IRQ_IXP4XX_GPIO5 (IRQ_IXP4XX_BASE + 22)
-#define IRQ_IXP4XX_GPIO6 (IRQ_IXP4XX_BASE + 23)
-#define IRQ_IXP4XX_GPIO7 (IRQ_IXP4XX_BASE + 24)
-#define IRQ_IXP4XX_GPIO8 (IRQ_IXP4XX_BASE + 25)
-#define IRQ_IXP4XX_GPIO9 (IRQ_IXP4XX_BASE + 26)
-#define IRQ_IXP4XX_GPIO10 (IRQ_IXP4XX_BASE + 27)
-#define IRQ_IXP4XX_GPIO11 (IRQ_IXP4XX_BASE + 28)
-#define IRQ_IXP4XX_GPIO12 (IRQ_IXP4XX_BASE + 29)
-#define IRQ_IXP4XX_SW_INT1 (IRQ_IXP4XX_BASE + 30)
-#define IRQ_IXP4XX_SW_INT2 (IRQ_IXP4XX_BASE + 31)
-#define IRQ_IXP4XX_USB_HOST (IRQ_IXP4XX_BASE + 32)
-#define IRQ_IXP4XX_I2C (IRQ_IXP4XX_BASE + 33)
-#define IRQ_IXP4XX_SSP (IRQ_IXP4XX_BASE + 34)
-#define IRQ_IXP4XX_TSYNC (IRQ_IXP4XX_BASE + 35)
-#define IRQ_IXP4XX_EAU_DONE (IRQ_IXP4XX_BASE + 36)
-#define IRQ_IXP4XX_SHA_DONE (IRQ_IXP4XX_BASE + 37)
-#define IRQ_IXP4XX_SWCP_PE (IRQ_IXP4XX_BASE + 58)
-#define IRQ_IXP4XX_QM_PE (IRQ_IXP4XX_BASE + 60)
-#define IRQ_IXP4XX_MCU_ECC (IRQ_IXP4XX_BASE + 61)
-#define IRQ_IXP4XX_EXP_PE (IRQ_IXP4XX_BASE + 62)
-
-#define _IXP4XX_GPIO_IRQ(n) (IRQ_IXP4XX_GPIO ## n)
-#define IXP4XX_GPIO_IRQ(n) _IXP4XX_GPIO_IRQ(n)
-
-#define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU)
-
-#endif
diff --git a/arch/arm/mach-mmp/sram.c b/arch/arm/mach-mmp/sram.c
index 6794e2db1ad5..ecc46c31004f 100644
--- a/arch/arm/mach-mmp/sram.c
+++ b/arch/arm/mach-mmp/sram.c
@@ -72,6 +72,8 @@ static int sram_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
+ platform_set_drvdata(pdev, info);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "no memory resource defined\n");
@@ -107,8 +109,6 @@ static int sram_probe(struct platform_device *pdev)
list_add(&info->node, &sram_bank_list);
mutex_unlock(&sram_lock);
- platform_set_drvdata(pdev, info);
-
dev_info(&pdev->dev, "initialized\n");
return 0;
@@ -127,17 +127,19 @@ static int sram_remove(struct platform_device *pdev)
struct sram_bank_info *info;
info = platform_get_drvdata(pdev);
- if (info == NULL)
- return -ENODEV;
- mutex_lock(&sram_lock);
- list_del(&info->node);
- mutex_unlock(&sram_lock);
+ if (info->sram_size) {
+ mutex_lock(&sram_lock);
+ list_del(&info->node);
+ mutex_unlock(&sram_lock);
+
+ gen_pool_destroy(info->gpool);
+ iounmap(info->sram_virt);
+ kfree(info->pool_name);
+ }
- gen_pool_destroy(info->gpool);
- iounmap(info->sram_virt);
- kfree(info->pool_name);
kfree(info);
+
return 0;
}
diff --git a/arch/arm/mach-mstar/Kconfig b/arch/arm/mach-mstar/Kconfig
index cd300eeedc20..5dbea7b485af 100644
--- a/arch/arm/mach-mstar/Kconfig
+++ b/arch/arm/mach-mstar/Kconfig
@@ -1,8 +1,10 @@
menuconfig ARCH_MSTARV7
bool "MStar/Sigmastar Armv7 SoC Support"
depends on ARCH_MULTI_V7
+ select ARM_ERRATA_814220
select ARM_GIC
select ARM_HEAVY_MB
+ select HAVE_ARM_ARCH_TIMER
select MST_IRQ
select MSTAR_MSC313_MPLL
help
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
index 788569e960e1..0b5f055ca1c3 100644
--- a/arch/arm/mach-mv78xx0/irq.c
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -67,7 +67,6 @@ void __init mv78xx0_init_irq(void)
* registers for core #1 are at an offset of 0x18 from those of
* core #0.)
*/
- orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE,
- mv78xx0_core_index() ? 0x18 : 0,
+ orion_gpio_init(0, 32, GPIO_VIRT_BASE, mv78xx0_core_index() ? 0x18 : 0,
IRQ_MV78XX0_GPIO_START, gpio0_irqs);
}
diff --git a/arch/arm/mach-nspire/Kconfig b/arch/arm/mach-nspire/Kconfig
index b3d161e8e2fb..6ef1b167619b 100644
--- a/arch/arm/mach-nspire/Kconfig
+++ b/arch/arm/mach-nspire/Kconfig
@@ -2,7 +2,6 @@
config ARCH_NSPIRE
bool "TI-NSPIRE based"
depends on ARCH_MULTI_V4_V5
- depends on MMU
select CPU_ARM926T
select GENERIC_IRQ_CHIP
select ARM_AMBA
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 6daaa645ae5d..21413a9b7b6c 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -263,9 +263,9 @@ static int __init omapdss_init_of(void)
}
r = of_platform_populate(node, NULL, NULL, &pdev->dev);
+ put_device(&pdev->dev);
if (r) {
pr_err("Unable to populate DSS submodule devices\n");
- put_device(&pdev->dev);
return r;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index ccb0e3732c0d..31d1a21f6041 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -752,8 +752,10 @@ static int __init _init_clkctrl_providers(void)
for_each_matching_node(np, ti_clkctrl_match_table) {
ret = _setup_clkctrl_provider(np);
- if (ret)
+ if (ret) {
+ of_node_put(np);
break;
+ }
}
return ret;
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index e94a61901ffd..c77f3b4e287b 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_ORION5X
bool "Marvell Orion"
- depends on MMU && ARCH_MULTI_V5
+ depends on ARCH_MULTI_V5
select CPU_FEROCEON
select GPIOLIB
select MVEBU_MBUS
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index ac4af2283bef..1ae775d02d90 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -49,6 +49,6 @@ void __init orion5x_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-31.
*/
- orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE, 0,
+ orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0,
IRQ_ORION5X_GPIO_START, gpio0_irqs);
}
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index f7520a6cc7d4..57f0be4065c1 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -153,16 +153,6 @@ config GUMSTIX_AM300EPD
endchoice
-config MACH_INTELMOTE2
- bool "Intel Mote 2 Platform"
- select IWMMXT
- select PXA27x
-
-config MACH_STARGATE2
- bool "Intel Stargate 2 Platform"
- select IWMMXT
- select PXA27x
-
config MACH_XCEP
bool "Iskratel Electronics XCEP"
select MTD
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 177abe584dd5..68730ceb8b7c 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -45,8 +45,6 @@ obj-$(CONFIG_MACH_CAPC7117) += capc7117.o mxm8x10.o
obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
obj-$(CONFIG_GUMSTIX_AM200EPD) += am200epd.o
obj-$(CONFIG_GUMSTIX_AM300EPD) += am300epd.o
-obj-$(CONFIG_MACH_INTELMOTE2) += stargate2.o
-obj-$(CONFIG_MACH_STARGATE2) += stargate2.o
obj-$(CONFIG_MACH_XCEP) += xcep.o
obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 593c7f793da5..44659fbc37ba 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -530,6 +530,16 @@ static struct pxa2xx_spi_controller corgi_spi_info = {
.num_chipselect = 3,
};
+static struct gpiod_lookup_table corgi_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.1",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void corgi_wait_for_hsync(void)
{
while (gpio_get_value(CORGI_GPIO_HSYNC))
@@ -548,10 +558,6 @@ static struct ads7846_platform_data corgi_ads7846_info = {
.wait_for_sync = corgi_wait_for_hsync,
};
-static struct pxa2xx_spi_chip corgi_ads7846_chip = {
- .gpio_cs = CORGI_GPIO_ADS7846_CS,
-};
-
static void corgi_bl_kick_battery(void)
{
void (*kick_batt)(void);
@@ -580,14 +586,6 @@ static struct corgi_lcd_platform_data corgi_lcdcon_info = {
.kick_battery = corgi_bl_kick_battery,
};
-static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
- .gpio_cs = CORGI_GPIO_LCDCON_CS,
-};
-
-static struct pxa2xx_spi_chip corgi_max1111_chip = {
- .gpio_cs = CORGI_GPIO_MAX1111_CS,
-};
-
static struct spi_board_info corgi_spi_devices[] = {
{
.modalias = "ads7846",
@@ -595,7 +593,6 @@ static struct spi_board_info corgi_spi_devices[] = {
.bus_num = 1,
.chip_select = 0,
.platform_data = &corgi_ads7846_info,
- .controller_data= &corgi_ads7846_chip,
.irq = PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT),
}, {
.modalias = "corgi-lcd",
@@ -603,18 +600,17 @@ static struct spi_board_info corgi_spi_devices[] = {
.bus_num = 1,
.chip_select = 1,
.platform_data = &corgi_lcdcon_info,
- .controller_data= &corgi_lcdcon_chip,
}, {
.modalias = "max1111",
.max_speed_hz = 450000,
.bus_num = 1,
.chip_select = 2,
- .controller_data= &corgi_max1111_chip,
},
};
static void __init corgi_init_spi(void)
{
+ gpiod_add_lookup_table(&corgi_spi_gpio_table);
pxa2xx_set_spi_info(1, &corgi_spi_info);
gpiod_add_lookup_table(&corgi_lcdcon_gpio_table);
spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 1d4c5db54be2..e1870fbb19e7 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -616,7 +616,6 @@ static struct pxa2xx_spi_chip tsc2046_chip = {
.tx_threshold = 1,
.rx_threshold = 2,
.timeout = 64,
- .gpio_cs = GPIO88_HX4700_TSC2046_CS,
};
static struct spi_board_info tsc2046_board_info[] __initdata = {
@@ -635,6 +634,14 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
.enable_dma = 1,
};
+static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_HX4700_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
/*
* External power
*/
@@ -896,6 +903,7 @@ static void __init hx4700_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info));
i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));
+ gpiod_add_lookup_table(&pxa_ssp2_gpio_table);
pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 04a12523cdee..753fe166ab68 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -13,7 +13,7 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/property.h>
-#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -42,7 +42,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
.rx_threshold = 128,
.dma_burst_size = 8,
.timeout = 235,
- .gpio_cs = ICONTROL_MCP251x_nCS1
};
static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
@@ -50,7 +49,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
.rx_threshold = 128,
.dma_burst_size = 8,
.timeout = 235,
- .gpio_cs = ICONTROL_MCP251x_nCS2
};
static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
@@ -58,7 +56,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
.rx_threshold = 128,
.dma_burst_size = 8,
.timeout = 235,
- .gpio_cs = ICONTROL_MCP251x_nCS3
};
static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
@@ -66,7 +63,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
.rx_threshold = 128,
.dma_burst_size = 8,
.timeout = 235,
- .gpio_cs = ICONTROL_MCP251x_nCS4
};
static const struct property_entry mcp251x_properties[] = {
@@ -143,6 +139,24 @@ struct platform_device pxa_spi_ssp4 = {
}
};
+static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
+ .dev_id = "pxa2xx-spi.3",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS1, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS2, "cs", 1, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table pxa_ssp4_gpio_table = {
+ .dev_id = "pxa2xx-spi.4",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS3, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS4, "cs", 1, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static struct platform_device *icontrol_spi_devices[] __initdata = {
&pxa_spi_ssp3,
&pxa_spi_ssp4,
@@ -175,6 +189,8 @@ static mfp_cfg_t mfp_can_cfg[] __initdata = {
static void __init icontrol_can_init(void)
{
pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
+ gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
+ gpiod_add_lookup_table(&pxa_ssp4_gpio_table);
platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
}
diff --git a/arch/arm/mach-pxa/include/mach/uncompress.h b/arch/arm/mach-pxa/include/mach/uncompress.h
index c36306064eee..1ed629e38ce6 100644
--- a/arch/arm/mach-pxa/include/mach/uncompress.h
+++ b/arch/arm/mach-pxa/include/mach/uncompress.h
@@ -58,9 +58,8 @@ static inline void arch_decomp_setup(void)
uart_shift = 2;
uart_is_pxa = 1;
- if (machine_is_littleton() || machine_is_intelmote2()
- || machine_is_csb726() || machine_is_stargate2()
- || machine_is_cm_x300() || machine_is_balloon3())
+ if (machine_is_littleton() || machine_is_csb726() ||
+ machine_is_cm_x300() || machine_is_balloon3())
uart_base = STUART_BASE;
if (machine_is_arcom_zeus()) {
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 793f61375ee8..73f5953b3bb6 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -195,7 +195,6 @@ static struct pxa2xx_spi_controller littleton_spi_info = {
static struct pxa2xx_spi_chip littleton_tdo24m_chip = {
.rx_threshold = 1,
.tx_threshold = 1,
- .gpio_cs = LITTLETON_GPIO_LCD_CS,
};
static struct spi_board_info littleton_spi_devices[] __initdata = {
@@ -208,8 +207,17 @@ static struct spi_board_info littleton_spi_devices[] __initdata = {
},
};
+static struct gpiod_lookup_table littleton_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", LITTLETON_GPIO_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void __init littleton_init_spi(void)
{
+ gpiod_add_lookup_table(&littleton_spi_gpio_table);
pxa2xx_set_spi_info(2, &littleton_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices));
}
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index cd9fa465b9b2..200fd35168e0 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -938,8 +938,6 @@ struct pxa2xx_spi_chip tsc2046_chip_info = {
.tx_threshold = 1,
.rx_threshold = 2,
.timeout = 64,
- /* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
- .gpio_cs = GPIO14_MAGICIAN_TSC2046_CS,
};
static struct pxa2xx_spi_controller magician_spi_info = {
@@ -947,6 +945,15 @@ static struct pxa2xx_spi_controller magician_spi_info = {
.enable_dma = 1,
};
+static struct gpiod_lookup_table magician_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ /* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
+ GPIO_LOOKUP_IDX("gpio-pxa", GPIO14_MAGICIAN_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static struct spi_board_info ads7846_spi_board_info[] __initdata = {
{
.modalias = "ads7846",
@@ -1031,6 +1038,7 @@ static void __init magician_init(void)
} else
pr_err("LCD detection: CPLD mapping failed\n");
+ gpiod_add_lookup_table(&magician_spi_gpio_table);
pxa2xx_set_spi_info(2, &magician_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 3a4ecc3c8f8b..58cfa434afde 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -197,6 +197,14 @@ static struct pxa2xx_spi_controller poodle_spi_info = {
.num_chipselect = 1,
};
+static struct gpiod_lookup_table poodle_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.1",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", POODLE_GPIO_TP_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static struct ads7846_platform_data poodle_ads7846_info = {
.model = 7846,
.vref_delay_usecs = 100,
@@ -205,23 +213,19 @@ static struct ads7846_platform_data poodle_ads7846_info = {
.gpio_pendown = POODLE_GPIO_TP_INT,
};
-static struct pxa2xx_spi_chip poodle_ads7846_chip = {
- .gpio_cs = POODLE_GPIO_TP_CS,
-};
-
static struct spi_board_info poodle_spi_devices[] = {
{
.modalias = "ads7846",
.max_speed_hz = 10000,
.bus_num = 1,
.platform_data = &poodle_ads7846_info,
- .controller_data= &poodle_ads7846_chip,
.irq = PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT),
},
};
static void __init poodle_init_spi(void)
{
+ gpiod_add_lookup_table(&poodle_spi_gpio_table);
pxa2xx_set_spi_info(1, &poodle_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
}
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 371008e9bb02..a648e7094e84 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -510,10 +510,6 @@ static struct ads7846_platform_data spitz_ads7846_info = {
.wait_for_sync = spitz_ads7846_wait_for_hsync,
};
-static struct pxa2xx_spi_chip spitz_ads7846_chip = {
- .gpio_cs = SPITZ_GPIO_ADS7846_CS,
-};
-
static void spitz_bl_kick_battery(void)
{
void (*kick_batt)(void);
@@ -555,14 +551,6 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = {
.kick_battery = spitz_bl_kick_battery,
};
-static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
- .gpio_cs = SPITZ_GPIO_LCDCON_CS,
-};
-
-static struct pxa2xx_spi_chip spitz_max1111_chip = {
- .gpio_cs = SPITZ_GPIO_MAX1111_CS,
-};
-
static struct spi_board_info spitz_spi_devices[] = {
{
.modalias = "ads7846",
@@ -570,7 +558,6 @@ static struct spi_board_info spitz_spi_devices[] = {
.bus_num = 2,
.chip_select = 0,
.platform_data = &spitz_ads7846_info,
- .controller_data = &spitz_ads7846_chip,
.irq = PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT),
}, {
.modalias = "corgi-lcd",
@@ -578,13 +565,11 @@ static struct spi_board_info spitz_spi_devices[] = {
.bus_num = 2,
.chip_select = 1,
.platform_data = &spitz_lcdcon_info,
- .controller_data = &spitz_lcdcon_chip,
}, {
.modalias = "max1111",
.max_speed_hz = 450000,
.bus_num = 2,
.chip_select = 2,
- .controller_data = &spitz_max1111_chip,
},
};
@@ -592,6 +577,16 @@ static struct pxa2xx_spi_controller spitz_spi_info = {
.num_chipselect = 3,
};
+static struct gpiod_lookup_table spitz_spi_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void __init spitz_spi_init(void)
{
if (machine_is_akita())
@@ -599,6 +594,7 @@ static void __init spitz_spi_init(void)
else
gpiod_add_lookup_table(&spitz_lcdcon_gpio_table);
+ gpiod_add_lookup_table(&spitz_spi_gpio_table);
pxa2xx_set_spi_info(2, &spitz_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
}
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
deleted file mode 100644
index 8ca02ec1d44c..000000000000
--- a/arch/arm/mach-pxa/stargate2.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-pxa/stargate2.c
- *
- * Author: Ed C. Epp
- * Created: Nov 05, 2002
- * Copyright: Intel Corp.
- *
- * Modified 2009: Jonathan Cameron <jic23@cam.ac.uk>
- */
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/bitops.h>
-#include <linux/fb.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/machine.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/mtd/partitions.h>
-
-#include <linux/platform_data/i2c-pxa.h>
-#include <linux/platform_data/pcf857x.h>
-#include <linux/smc91x.h>
-#include <linux/gpio/machine.h>
-#include <linux/gpio.h>
-#include <linux/leds.h>
-#include <linux/property.h>
-
-#include <asm/types.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/flash.h>
-
-#include "pxa27x.h"
-#include <linux/platform_data/mmc-pxamci.h>
-#include "udc.h"
-#include "pxa27x-udc.h"
-#include <mach/smemc.h>
-
-#include <linux/spi/spi.h>
-#include <linux/spi/pxa2xx_spi.h>
-#include <linux/mfd/da903x.h>
-
-#include "devices.h"
-#include "generic.h"
-
-#define STARGATE_NR_IRQS (IRQ_BOARD_START + 8)
-
-/* Bluetooth */
-#define SG2_BT_RESET 81
-
-/* SD */
-#define SG2_GPIO_nSD_DETECT 90
-#define SG2_SD_POWER_ENABLE 89
-
-static unsigned long sg2_im2_unified_pin_config[] __initdata = {
- /* Device Identification for wakeup*/
- GPIO102_GPIO,
- /* DA9030 */
- GPIO1_GPIO,
-
- /* MMC */
- GPIO32_MMC_CLK,
- GPIO112_MMC_CMD,
- GPIO92_MMC_DAT_0,
- GPIO109_MMC_DAT_1,
- GPIO110_MMC_DAT_2,
- GPIO111_MMC_DAT_3,
-
- /* 802.15.4 radio - driver out of mainline */
- GPIO22_GPIO, /* CC_RSTN */
- GPIO114_GPIO, /* CC_FIFO */
- GPIO116_GPIO, /* CC_CCA */
- GPIO0_GPIO, /* CC_FIFOP */
- GPIO16_GPIO, /* CCSFD */
- GPIO115_GPIO, /* Power enable */
-
- /* I2C */
- GPIO117_I2C_SCL,
- GPIO118_I2C_SDA,
-
- /* SSP 3 - 802.15.4 radio */
- GPIO39_GPIO, /* Chip Select */
- GPIO34_SSP3_SCLK,
- GPIO35_SSP3_TXD,
- GPIO41_SSP3_RXD,
-
- /* SSP 2 to daughter boards */
- GPIO11_SSP2_RXD,
- GPIO38_SSP2_TXD,
- GPIO36_SSP2_SCLK,
- GPIO37_GPIO, /* chip select */
-
- /* SSP 1 - to daughter boards */
- GPIO24_GPIO, /* Chip Select */
- GPIO23_SSP1_SCLK,
- GPIO25_SSP1_TXD,
- GPIO26_SSP1_RXD,
-
- /* BTUART Basic Connector*/
- GPIO42_BTUART_RXD,
- GPIO43_BTUART_TXD,
- GPIO44_BTUART_CTS,
- GPIO45_BTUART_RTS,
-
- /* STUART - IM2 via debug board not sure on SG2*/
- GPIO46_STUART_RXD,
- GPIO47_STUART_TXD,
-
- /* Basic sensor board */
- GPIO96_GPIO, /* accelerometer interrupt */
- GPIO99_GPIO, /* ADC interrupt */
-
- /* SHT15 */
- GPIO100_GPIO,
- GPIO98_GPIO,
-
- /* Basic sensor board */
- GPIO96_GPIO, /* accelerometer interrupt */
- GPIO99_GPIO, /* ADC interrupt */
-
- /* Connector pins specified as gpios */
- GPIO94_GPIO, /* large basic connector pin 14 */
- GPIO10_GPIO, /* large basic connector pin 23 */
-};
-
-static struct gpiod_lookup_table sht15_gpiod_table = {
- .dev_id = "sht15",
- .table = {
- /* FIXME: should this have |GPIO_OPEN_DRAIN set? */
- GPIO_LOOKUP("gpio-pxa", 100, "data", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("gpio-pxa", 98, "clk", GPIO_ACTIVE_HIGH),
- },
-};
-
-static struct platform_device sht15 = {
- .name = "sht15",
- .id = -1,
-};
-
-static struct regulator_consumer_supply stargate2_sensor_3_con[] = {
- REGULATOR_SUPPLY("vcc", "sht15"),
-};
-
-enum stargate2_ldos{
- vcc_vref,
- vcc_cc2420,
- /* a mote connector? */
- vcc_mica,
- /* the CSR bluecore chip */
- vcc_bt,
- /* The two voltages available to sensor boards */
- vcc_sensor_1_8,
- vcc_sensor_3,
- /* directly connected to the pxa27x */
- vcc_sram_ext,
- vcc_pxa_pll,
- vcc_pxa_usim, /* Reference voltage for certain gpios */
- vcc_pxa_mem,
- vcc_pxa_flash,
- vcc_pxa_core, /*Dc-Dc buck not yet supported */
- vcc_lcd,
- vcc_bb,
- vcc_bbio, /*not sure!*/
- vcc_io, /* cc2420 802.15.4 radio and pxa vcc_io ?*/
-};
-
-/* The values of the various regulator constraints are obviously dependent
- * on exactly what is wired to each ldo. Unfortunately this information is
- * not generally available. More information has been requested from Xbow.
- */
-static struct regulator_init_data stargate2_ldo_init_data[] = {
- [vcc_bbio] = {
- .constraints = { /* board default 1.8V */
- .name = "vcc_bbio",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
- [vcc_bb] = {
- .constraints = { /* board default 2.8V */
- .name = "vcc_bb",
- .min_uV = 2700000,
- .max_uV = 3000000,
- },
- },
- [vcc_pxa_flash] = {
- .constraints = {/* default is 1.8V */
- .name = "vcc_pxa_flash",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
- [vcc_cc2420] = { /* also vcc_io */
- .constraints = {
- /* board default is 2.8V */
- .name = "vcc_cc2420",
- .min_uV = 2700000,
- .max_uV = 3300000,
- },
- },
- [vcc_vref] = { /* Reference for what? */
- .constraints = { /* default 1.8V */
- .name = "vcc_vref",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
- [vcc_sram_ext] = {
- .constraints = { /* default 2.8V */
- .name = "vcc_sram_ext",
- .min_uV = 2800000,
- .max_uV = 2800000,
- },
- },
- [vcc_mica] = {
- .constraints = { /* default 2.8V */
- .name = "vcc_mica",
- .min_uV = 2800000,
- .max_uV = 2800000,
- },
- },
- [vcc_bt] = {
- .constraints = { /* default 2.8V */
- .name = "vcc_bt",
- .min_uV = 2800000,
- .max_uV = 2800000,
- },
- },
- [vcc_lcd] = {
- .constraints = { /* default 2.8V */
- .name = "vcc_lcd",
- .min_uV = 2700000,
- .max_uV = 3300000,
- },
- },
- [vcc_io] = { /* Same or higher than everything
- * bar vccbat and vccusb */
- .constraints = { /* default 2.8V */
- .name = "vcc_io",
- .min_uV = 2692000,
- .max_uV = 3300000,
- },
- },
- [vcc_sensor_1_8] = {
- .constraints = { /* default 1.8V */
- .name = "vcc_sensor_1_8",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
- [vcc_sensor_3] = { /* curiously default 2.8V */
- .constraints = {
- .name = "vcc_sensor_3",
- .min_uV = 2800000,
- .max_uV = 3000000,
- },
- .num_consumer_supplies = ARRAY_SIZE(stargate2_sensor_3_con),
- .consumer_supplies = stargate2_sensor_3_con,
- },
- [vcc_pxa_pll] = { /* 1.17V - 1.43V, default 1.3V*/
- .constraints = {
- .name = "vcc_pxa_pll",
- .min_uV = 1170000,
- .max_uV = 1430000,
- },
- },
- [vcc_pxa_usim] = {
- .constraints = { /* default 1.8V */
- .name = "vcc_pxa_usim",
- .min_uV = 1710000,
- .max_uV = 2160000,
- },
- },
- [vcc_pxa_mem] = {
- .constraints = { /* default 1.8V */
- .name = "vcc_pxa_mem",
- .min_uV = 1800000,
- .max_uV = 1800000,
- },
- },
-};
-
-static struct mtd_partition stargate2flash_partitions[] = {
- {
- .name = "Bootloader",
- .size = 0x00040000,
- .offset = 0,
- .mask_flags = 0,
- }, {
- .name = "Kernel",
- .size = 0x00200000,
- .offset = 0x00040000,
- .mask_flags = 0
- }, {
- .name = "Filesystem",
- .size = 0x01DC0000,
- .offset = 0x00240000,
- .mask_flags = 0
- },
-};
-
-static struct resource flash_resources = {
- .start = PXA_CS0_PHYS,
- .end = PXA_CS0_PHYS + SZ_32M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct flash_platform_data stargate2_flash_data = {
- .map_name = "cfi_probe",
- .parts = stargate2flash_partitions,
- .nr_parts = ARRAY_SIZE(stargate2flash_partitions),
- .name = "PXA27xOnChipROM",
- .width = 2,
-};
-
-static struct platform_device stargate2_flash_device = {
- .name = "pxa2xx-flash",
- .id = 0,
- .dev = {
- .platform_data = &stargate2_flash_data,
- },
- .resource = &flash_resources,
- .num_resources = 1,
-};
-
-static struct pxa2xx_spi_controller pxa_ssp_master_0_info = {
- .num_chipselect = 1,
-};
-
-static struct pxa2xx_spi_controller pxa_ssp_master_1_info = {
- .num_chipselect = 1,
-};
-
-static struct pxa2xx_spi_controller pxa_ssp_master_2_info = {
- .num_chipselect = 1,
-};
-
-/* An upcoming kernel change will scrap SFRM usage so these
- * drivers have been moved to use GPIOs */
-static struct pxa2xx_spi_chip staccel_chip_info = {
- .tx_threshold = 8,
- .rx_threshold = 8,
- .dma_burst_size = 8,
- .timeout = 235,
- .gpio_cs = 24,
-};
-
-static struct pxa2xx_spi_chip cc2420_info = {
- .tx_threshold = 8,
- .rx_threshold = 8,
- .dma_burst_size = 8,
- .timeout = 235,
- .gpio_cs = 39,
-};
-
-static struct spi_board_info spi_board_info[] __initdata = {
- {
- .modalias = "lis3l02dq",
- .max_speed_hz = 8000000,/* 8MHz max spi frequency at 3V */
- .bus_num = 1,
- .chip_select = 0,
- .controller_data = &staccel_chip_info,
- .irq = PXA_GPIO_TO_IRQ(96),
- }, {
- .modalias = "cc2420",
- .max_speed_hz = 6500000,
- .bus_num = 3,
- .chip_select = 0,
- .controller_data = &cc2420_info,
- },
-};
-
-static void sg2_udc_command(int cmd)
-{
- switch (cmd) {
- case PXA2XX_UDC_CMD_CONNECT:
- UP2OCR |= UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE;
- break;
- case PXA2XX_UDC_CMD_DISCONNECT:
- UP2OCR &= ~(UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE);
- break;
- }
-}
-
-static struct i2c_pxa_platform_data i2c_pwr_pdata = {
- .fast_mode = 1,
-};
-
-static struct i2c_pxa_platform_data i2c_pdata = {
- .fast_mode = 1,
-};
-
-static void __init imote2_stargate2_init(void)
-{
-
- pxa2xx_mfp_config(ARRAY_AND_SIZE(sg2_im2_unified_pin_config));
-
- pxa_set_ffuart_info(NULL);
- pxa_set_btuart_info(NULL);
- pxa_set_stuart_info(NULL);
-
- pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
- pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info);
- pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info);
- spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
-
-
- pxa27x_set_i2c_power_info(&i2c_pwr_pdata);
- pxa_set_i2c_info(&i2c_pdata);
-}
-
-#ifdef CONFIG_MACH_INTELMOTE2
-/* As the the imote2 doesn't currently have a conventional SD slot
- * there is no option to hotplug cards, making all this rather simple
- */
-static int imote2_mci_get_ro(struct device *dev)
-{
- return 0;
-}
-
-/* Rather simple case as hotplugging not possible */
-static struct pxamci_platform_data imote2_mci_platform_data = {
- .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* default anyway */
- .get_ro = imote2_mci_get_ro,
-};
-
-static struct gpio_led imote2_led_pins[] = {
- {
- .name = "imote2:red",
- .gpio = 103,
- .active_low = 1,
- }, {
- .name = "imote2:green",
- .gpio = 104,
- .active_low = 1,
- }, {
- .name = "imote2:blue",
- .gpio = 105,
- .active_low = 1,
- },
-};
-
-static struct gpio_led_platform_data imote2_led_data = {
- .num_leds = ARRAY_SIZE(imote2_led_pins),
- .leds = imote2_led_pins,
-};
-
-static struct platform_device imote2_leds = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &imote2_led_data,
- },
-};
-
-static struct da903x_subdev_info imote2_da9030_subdevs[] = {
- {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO2,
- .platform_data = &stargate2_ldo_init_data[vcc_bbio],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO3,
- .platform_data = &stargate2_ldo_init_data[vcc_bb],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO4,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO5,
- .platform_data = &stargate2_ldo_init_data[vcc_cc2420],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO6,
- .platform_data = &stargate2_ldo_init_data[vcc_vref],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO7,
- .platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO8,
- .platform_data = &stargate2_ldo_init_data[vcc_mica],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO9,
- .platform_data = &stargate2_ldo_init_data[vcc_bt],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO10,
- .platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO11,
- .platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO12,
- .platform_data = &stargate2_ldo_init_data[vcc_lcd],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO15,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO17,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
- }, {
- .name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
- .id = DA9030_ID_LDO18,
- .platform_data = &stargate2_ldo_init_data[vcc_io],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO19,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
- },
-};
-
-static struct da903x_platform_data imote2_da9030_pdata = {
- .num_subdevs = ARRAY_SIZE(imote2_da9030_subdevs),
- .subdevs = imote2_da9030_subdevs,
-};
-
-static struct i2c_board_info __initdata imote2_pwr_i2c_board_info[] = {
- {
- .type = "da9030",
- .addr = 0x49,
- .platform_data = &imote2_da9030_pdata,
- .irq = PXA_GPIO_TO_IRQ(1),
- },
-};
-
-static struct i2c_board_info __initdata imote2_i2c_board_info[] = {
- { /* UCAM sensor board */
- .type = "max1239",
- .addr = 0x35,
- }, { /* ITS400 Sensor board only */
- .type = "max1363",
- .addr = 0x34,
- /* Through a nand gate - Also beware, on V2 sensor board the
- * pull up resistors are missing.
- */
- .irq = PXA_GPIO_TO_IRQ(99),
- }, { /* ITS400 Sensor board only */
- .type = "tsl2561",
- .addr = 0x49,
- /* Through a nand gate - Also beware, on V2 sensor board the
- * pull up resistors are missing.
- */
- .irq = PXA_GPIO_TO_IRQ(99),
- }, { /* ITS400 Sensor board only */
- .type = "tmp175",
- .addr = 0x4A,
- .irq = PXA_GPIO_TO_IRQ(96),
- }, { /* IMB400 Multimedia board */
- .type = "wm8940",
- .addr = 0x1A,
- },
-};
-
-static unsigned long imote2_pin_config[] __initdata = {
-
- /* Button */
- GPIO91_GPIO,
-
- /* LEDS */
- GPIO103_GPIO, /* red led */
- GPIO104_GPIO, /* green led */
- GPIO105_GPIO, /* blue led */
-};
-
-static struct pxa2xx_udc_mach_info imote2_udc_info __initdata = {
- .udc_command = sg2_udc_command,
-};
-
-static struct platform_device imote2_audio_device = {
- .name = "imote2-audio",
- .id = -1,
-};
-
-static struct platform_device *imote2_devices[] = {
- &stargate2_flash_device,
- &imote2_leds,
- &sht15,
- &imote2_audio_device,
-};
-
-static void __init imote2_init(void)
-{
- pxa2xx_mfp_config(ARRAY_AND_SIZE(imote2_pin_config));
-
- imote2_stargate2_init();
-
- gpiod_add_lookup_table(&sht15_gpiod_table);
- platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
-
- i2c_register_board_info(0, imote2_i2c_board_info,
- ARRAY_SIZE(imote2_i2c_board_info));
- i2c_register_board_info(1, imote2_pwr_i2c_board_info,
- ARRAY_SIZE(imote2_pwr_i2c_board_info));
-
- pxa_set_mci_info(&imote2_mci_platform_data);
- pxa_set_udc_info(&imote2_udc_info);
-}
-#endif
-
-#ifdef CONFIG_MACH_STARGATE2
-
-static unsigned long stargate2_pin_config[] __initdata = {
-
- GPIO15_nCS_1, /* SRAM */
- /* SMC91x */
- GPIO80_nCS_4,
- GPIO40_GPIO, /*cable detect?*/
-
- /* Button */
- GPIO91_GPIO | WAKEUP_ON_LEVEL_HIGH,
-
- /* Compact Flash */
- GPIO79_PSKTSEL,
- GPIO48_nPOE,
- GPIO49_nPWE,
- GPIO50_nPIOR,
- GPIO51_nPIOW,
- GPIO85_nPCE_1,
- GPIO54_nPCE_2,
- GPIO55_nPREG,
- GPIO56_nPWAIT,
- GPIO57_nIOIS16,
- GPIO120_GPIO, /* Buff ctrl */
- GPIO108_GPIO, /* Power ctrl */
- GPIO82_GPIO, /* Reset */
- GPIO53_GPIO, /* SG2_S0_GPIO_DETECT */
-
- /* MMC not shared with imote2 */
- GPIO90_GPIO, /* nSD detect */
- GPIO89_GPIO, /* SD_POWER_ENABLE */
-
- /* Bluetooth */
- GPIO81_GPIO, /* reset */
-};
-
-static struct resource smc91x_resources[] = {
- [0] = {
- .name = "smc91x-regs",
- .start = (PXA_CS4_PHYS + 0x300),
- .end = (PXA_CS4_PHYS + 0xfffff),
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = PXA_GPIO_TO_IRQ(40),
- .end = PXA_GPIO_TO_IRQ(40),
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
- }
-};
-
-static struct smc91x_platdata stargate2_smc91x_info = {
- .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT
- | SMC91X_NOWAIT | SMC91X_USE_DMA,
- .pxa_u16_align4 = true,
-};
-
-static struct platform_device smc91x_device = {
- .name = "smc91x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smc91x_resources),
- .resource = smc91x_resources,
- .dev = {
- .platform_data = &stargate2_smc91x_info,
- },
-};
-
-
-/*
- * The card detect interrupt isn't debounced so we delay it by 250ms
- * to give the card a chance to fully insert / eject.
- */
-static int stargate2_mci_init(struct device *dev,
- irq_handler_t stargate2_detect_int,
- void *data)
-{
- int err;
-
- err = gpio_request(SG2_SD_POWER_ENABLE, "SG2_sd_power_enable");
- if (err) {
- printk(KERN_ERR "Can't get the gpio for SD power control");
- goto return_err;
- }
- gpio_direction_output(SG2_SD_POWER_ENABLE, 0);
-
- err = gpio_request(SG2_GPIO_nSD_DETECT, "SG2_sd_detect");
- if (err) {
- printk(KERN_ERR "Can't get the sd detect gpio");
- goto free_power_en;
- }
- gpio_direction_input(SG2_GPIO_nSD_DETECT);
-
- err = request_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT),
- stargate2_detect_int,
- IRQ_TYPE_EDGE_BOTH,
- "MMC card detect",
- data);
- if (err) {
- printk(KERN_ERR "can't request MMC card detect IRQ\n");
- goto free_nsd_detect;
- }
- return 0;
-
- free_nsd_detect:
- gpio_free(SG2_GPIO_nSD_DETECT);
- free_power_en:
- gpio_free(SG2_SD_POWER_ENABLE);
- return_err:
- return err;
-}
-
-/**
- * stargate2_mci_setpower() - set state of mmc power supply
- *
- * Very simple control. Either it is on or off and is controlled by
- * a gpio pin */
-static int stargate2_mci_setpower(struct device *dev, unsigned int vdd)
-{
- gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd);
- return 0;
-}
-
-static void stargate2_mci_exit(struct device *dev, void *data)
-{
- free_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT), data);
- gpio_free(SG2_SD_POWER_ENABLE);
- gpio_free(SG2_GPIO_nSD_DETECT);
-}
-
-static struct pxamci_platform_data stargate2_mci_platform_data = {
- .detect_delay_ms = 250,
- .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
- .init = stargate2_mci_init,
- .setpower = stargate2_mci_setpower,
- .exit = stargate2_mci_exit,
-};
-
-
-/*
- * SRAM - The Stargate 2 has 32MB of SRAM.
- *
- * Here it is made available as an MTD. This will then
- * typically have a cifs filesystem created on it to provide
- * fast temporary storage.
- */
-static struct resource sram_resources = {
- .start = PXA_CS1_PHYS,
- .end = PXA_CS1_PHYS + SZ_32M-1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platdata_mtd_ram stargate2_sram_pdata = {
- .mapname = "Stargate2 SRAM",
- .bankwidth = 2,
-};
-
-static struct platform_device stargate2_sram = {
- .name = "mtd-ram",
- .id = 0,
- .resource = &sram_resources,
- .num_resources = 1,
- .dev = {
- .platform_data = &stargate2_sram_pdata,
- },
-};
-
-static struct pcf857x_platform_data platform_data_pcf857x = {
- .gpio_base = 128,
- .n_latch = 0,
- .setup = NULL,
- .teardown = NULL,
- .context = NULL,
-};
-
-static const struct property_entry pca9500_eeprom_properties[] = {
- PROPERTY_ENTRY_U32("pagesize", 4),
- { }
-};
-
-static const struct software_node pca9500_eeprom_node = {
- .properties = pca9500_eeprom_properties,
-};
-
-/**
- * stargate2_reset_bluetooth() reset the bluecore to ensure consistent state
- **/
-static int stargate2_reset_bluetooth(void)
-{
- int err;
- err = gpio_request(SG2_BT_RESET, "SG2_BT_RESET");
- if (err) {
- printk(KERN_ERR "Could not get gpio for bluetooth reset\n");
- return err;
- }
- gpio_direction_output(SG2_BT_RESET, 1);
- mdelay(5);
- /* now reset it - 5 msec minimum */
- gpio_set_value(SG2_BT_RESET, 0);
- mdelay(10);
- gpio_set_value(SG2_BT_RESET, 1);
- gpio_free(SG2_BT_RESET);
- return 0;
-}
-
-static struct led_info stargate2_leds[] = {
- {
- .name = "sg2:red",
- .flags = DA9030_LED_RATE_ON,
- }, {
- .name = "sg2:blue",
- .flags = DA9030_LED_RATE_ON,
- }, {
- .name = "sg2:green",
- .flags = DA9030_LED_RATE_ON,
- },
-};
-
-static struct da903x_subdev_info stargate2_da9030_subdevs[] = {
- {
- .name = "da903x-led",
- .id = DA9030_ID_LED_2,
- .platform_data = &stargate2_leds[0],
- }, {
- .name = "da903x-led",
- .id = DA9030_ID_LED_3,
- .platform_data = &stargate2_leds[2],
- }, {
- .name = "da903x-led",
- .id = DA9030_ID_LED_4,
- .platform_data = &stargate2_leds[1],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO2,
- .platform_data = &stargate2_ldo_init_data[vcc_bbio],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO3,
- .platform_data = &stargate2_ldo_init_data[vcc_bb],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO4,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO5,
- .platform_data = &stargate2_ldo_init_data[vcc_cc2420],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO6,
- .platform_data = &stargate2_ldo_init_data[vcc_vref],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO7,
- .platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO8,
- .platform_data = &stargate2_ldo_init_data[vcc_mica],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO9,
- .platform_data = &stargate2_ldo_init_data[vcc_bt],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO10,
- .platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO11,
- .platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO12,
- .platform_data = &stargate2_ldo_init_data[vcc_lcd],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO15,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO17,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
- }, {
- .name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
- .id = DA9030_ID_LDO18,
- .platform_data = &stargate2_ldo_init_data[vcc_io],
- }, {
- .name = "da903x-regulator",
- .id = DA9030_ID_LDO19,
- .platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
- },
-};
-
-static struct da903x_platform_data stargate2_da9030_pdata = {
- .num_subdevs = ARRAY_SIZE(stargate2_da9030_subdevs),
- .subdevs = stargate2_da9030_subdevs,
-};
-
-static struct i2c_board_info __initdata stargate2_pwr_i2c_board_info[] = {
- {
- .type = "da9030",
- .addr = 0x49,
- .platform_data = &stargate2_da9030_pdata,
- .irq = PXA_GPIO_TO_IRQ(1),
- },
-};
-
-static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {
- /* Techically this a pca9500 - but it's compatible with the 8574
- * for gpio expansion and the 24c02 for eeprom access.
- */
- {
- .type = "pcf8574",
- .addr = 0x27,
- .platform_data = &platform_data_pcf857x,
- }, {
- .type = "24c02",
- .addr = 0x57,
- .swnode = &pca9500_eeprom_node,
- }, {
- .type = "max1238",
- .addr = 0x35,
- }, { /* ITS400 Sensor board only */
- .type = "max1363",
- .addr = 0x34,
- /* Through a nand gate - Also beware, on V2 sensor board the
- * pull up resistors are missing.
- */
- .irq = PXA_GPIO_TO_IRQ(99),
- }, { /* ITS400 Sensor board only */
- .type = "tsl2561",
- .addr = 0x49,
- /* Through a nand gate - Also beware, on V2 sensor board the
- * pull up resistors are missing.
- */
- .irq = PXA_GPIO_TO_IRQ(99),
- }, { /* ITS400 Sensor board only */
- .type = "tmp175",
- .addr = 0x4A,
- .irq = PXA_GPIO_TO_IRQ(96),
- },
-};
-
-/* Board doesn't support cable detection - so always lie and say
- * something is there.
- */
-static int sg2_udc_detect(void)
-{
- return 1;
-}
-
-static struct pxa2xx_udc_mach_info stargate2_udc_info __initdata = {
- .udc_is_connected = sg2_udc_detect,
- .udc_command = sg2_udc_command,
-};
-
-static struct platform_device *stargate2_devices[] = {
- &stargate2_flash_device,
- &stargate2_sram,
- &smc91x_device,
- &sht15,
-};
-
-static void __init stargate2_init(void)
-{
- /* This is probably a board specific hack as this must be set
- prior to connecting the MFP stuff up. */
- __raw_writel(__raw_readl(MECR) & ~MECR_NOS, MECR);
-
- pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config));
-
- imote2_stargate2_init();
-
- gpiod_add_lookup_table(&sht15_gpiod_table);
- platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
-
- i2c_register_board_info(0, ARRAY_AND_SIZE(stargate2_i2c_board_info));
- i2c_register_board_info(1, stargate2_pwr_i2c_board_info,
- ARRAY_SIZE(stargate2_pwr_i2c_board_info));
-
- pxa_set_mci_info(&stargate2_mci_platform_data);
-
- pxa_set_udc_info(&stargate2_udc_info);
-
- stargate2_reset_bluetooth();
-}
-#endif
-
-#ifdef CONFIG_MACH_INTELMOTE2
-MACHINE_START(INTELMOTE2, "IMOTE 2")
- .map_io = pxa27x_map_io,
- .nr_irqs = PXA_NR_IRQS,
- .init_irq = pxa27x_init_irq,
- .handle_irq = pxa27x_handle_irq,
- .init_time = pxa_timer_init,
- .init_machine = imote2_init,
- .atag_offset = 0x100,
- .restart = pxa_restart,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_STARGATE2
-MACHINE_START(STARGATE2, "Stargate 2")
- .map_io = pxa27x_map_io,
- .nr_irqs = STARGATE_NR_IRQS,
- .init_irq = pxa27x_init_irq,
- .handle_irq = pxa27x_handle_irq,
- .init_time = pxa_timer_init,
- .init_machine = stargate2_init,
- .atag_offset = 0x100,
- .restart = pxa_restart,
-MACHINE_END
-#endif
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index 8e74fbb0a96e..7eaeda269927 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -570,7 +570,6 @@ static struct pxa2xx_spi_chip z2_lbs_chip_info = {
.rx_threshold = 8,
.tx_threshold = 8,
.timeout = 1000,
- .gpio_cs = GPIO24_ZIPITZ2_WIFI_CS,
};
static struct libertas_spi_platform_data z2_lbs_pdata = {
@@ -584,7 +583,6 @@ static struct pxa2xx_spi_chip lms283_chip_info = {
.rx_threshold = 1,
.tx_threshold = 1,
.timeout = 64,
- .gpio_cs = GPIO88_ZIPITZ2_LCD_CS,
};
static struct gpiod_lookup_table lms283_gpio_table = {
@@ -624,8 +622,26 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
.num_chipselect = 1,
};
+static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
+ .dev_id = "pxa2xx-spi.1",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", GPIO24_ZIPITZ2_WIFI_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
+ .dev_id = "pxa2xx-spi.2",
+ .table = {
+ GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_ZIPITZ2_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void __init z2_spi_init(void)
{
+ gpiod_add_lookup_table(&pxa_ssp1_gpio_table);
+ gpiod_add_lookup_table(&pxa_ssp2_gpio_table);
pxa2xx_set_spi_info(1, &pxa_ssp1_master_info);
pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
gpiod_add_lookup_table(&lms283_gpio_table);
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index 58a4228455ce..65a0d5ce2bb3 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -357,8 +357,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
{
int cpu;
- if (qcom_scm_set_cold_boot_addr(secondary_startup_arm,
- cpu_present_mask)) {
+ if (qcom_scm_set_cold_boot_addr(secondary_startup_arm)) {
for_each_present_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
diff --git a/arch/arm/mach-rpc/fiq.S b/arch/arm/mach-rpc/fiq.S
index 0de83e9b0b39..087bdf4bc093 100644
--- a/arch/arm/mach-rpc/fiq.S
+++ b/arch/arm/mach-rpc/fiq.S
@@ -2,10 +2,11 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/hardware.h>
-#include <mach/entry-macro.S>
- .text
+ .equ ioc_base_high, IOC_BASE & 0xff000000
+ .equ ioc_base_low, IOC_BASE & 0x00ff0000
+ .text
.global rpc_default_fiq_end
ENTRY(rpc_default_fiq_start)
mov r12, #ioc_base_high
diff --git a/arch/arm/mach-rpc/include/mach/entry-macro.S b/arch/arm/mach-rpc/include/mach/entry-macro.S
deleted file mode 100644
index a6d1a9f4bb79..000000000000
--- a/arch/arm/mach-rpc/include/mach/entry-macro.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <mach/hardware.h>
-#include <asm/hardware/entry-macro-iomd.S>
-
- .equ ioc_base_high, IOC_BASE & 0xff000000
- .equ ioc_base_low, IOC_BASE & 0x00ff0000
-
- .macro get_irqnr_preamble, base, tmp
- mov \base, #ioc_base_high @ point at IOC
- .if ioc_base_low
- orr \base, \base, #ioc_base_low
- .endif
- .endm
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index 803aeb126f0e..dc29384b6ef8 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -14,6 +14,99 @@
#define CLR 0x04
#define MASK 0x08
+static const u8 irq_prio_h[256] = {
+ 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
+ 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
+ 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+};
+
+static const u8 irq_prio_d[256] = {
+ 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+};
+
+static const u8 irq_prio_l[256] = {
+ 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+ 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+static int iomd_get_irq_nr(void)
+{
+ int irq;
+ u8 reg;
+
+ /* get highest priority first */
+ reg = readb(IOC_BASE + IOMD_IRQREQB);
+ irq = irq_prio_h[reg];
+ if (irq)
+ return irq;
+
+ /* get DMA */
+ reg = readb(IOC_BASE + IOMD_DMAREQ);
+ irq = irq_prio_d[reg];
+ if (irq)
+ return irq;
+
+ /* get low priority */
+ reg = readb(IOC_BASE + IOMD_IRQREQA);
+ irq = irq_prio_l[reg];
+ if (irq)
+ return irq;
+ return 0;
+}
+
+static void iomd_handle_irq(struct pt_regs *regs)
+{
+ int irq;
+
+ do {
+ irq = iomd_get_irq_nr();
+ if (irq)
+ generic_handle_irq(irq);
+ } while (irq);
+}
+
static void __iomem *iomd_get_base(struct irq_data *d)
{
void *cd = irq_data_get_irq_chip_data(d);
@@ -82,6 +175,8 @@ void __init rpc_init_irq(void)
set_fiq_handler(&rpc_default_fiq_start,
&rpc_default_fiq_end - &rpc_default_fiq_start);
+ set_handle_irq(iomd_handle_irq);
+
for (irq = 0; irq < NR_IRQS; irq++) {
clr = IRQ_NOREQUEST;
set = 0;
diff --git a/arch/arm/mach-s3c/Kconfig b/arch/arm/mach-s3c/Kconfig
index 25606e668cf9..1899fc3f44fd 100644
--- a/arch/arm/mach-s3c/Kconfig
+++ b/arch/arm/mach-s3c/Kconfig
@@ -191,18 +191,6 @@ config S3C64XX_DEV_SPI0
Compile in platform device definitions for S3C64XX's type
SPI controller 0
-config S3C64XX_DEV_SPI1
- bool
- help
- Compile in platform device definitions for S3C64XX's type
- SPI controller 1
-
-config S3C64XX_DEV_SPI2
- bool
- help
- Compile in platform device definitions for S3C64XX's type
- SPI controller 2
-
config SAMSUNG_DEV_TS
bool
help
diff --git a/arch/arm/mach-s3c/devs.c b/arch/arm/mach-s3c/devs.c
index 06dec64848f9..1e266fc24f9b 100644
--- a/arch/arm/mach-s3c/devs.c
+++ b/arch/arm/mach-s3c/devs.c
@@ -1107,8 +1107,7 @@ struct platform_device s3c64xx_device_spi0 = {
},
};
-void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
- int num_cs)
+void __init s3c64xx_spi0_set_platdata(int src_clk_nr, int num_cs)
{
struct s3c64xx_spi_info pd;
@@ -1120,80 +1119,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr;
- pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
+ pd.cfg_gpio = s3c64xx_spi0_cfg_gpio;
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
}
#endif /* CONFIG_S3C64XX_DEV_SPI0 */
-
-#ifdef CONFIG_S3C64XX_DEV_SPI1
-static struct resource s3c64xx_spi1_resource[] = {
- [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256),
- [1] = DEFINE_RES_IRQ(IRQ_SPI1),
-};
-
-struct platform_device s3c64xx_device_spi1 = {
- .name = "s3c6410-spi",
- .id = 1,
- .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
- .resource = s3c64xx_spi1_resource,
- .dev = {
- .dma_mask = &samsung_device_dma_mask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
-
-void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
- int num_cs)
-{
- struct s3c64xx_spi_info pd;
-
- /* Reject invalid configuration */
- if (!num_cs || src_clk_nr < 0) {
- pr_err("%s: Invalid SPI configuration\n", __func__);
- return;
- }
-
- pd.num_cs = num_cs;
- pd.src_clk_nr = src_clk_nr;
- pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
-
- s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
-}
-#endif /* CONFIG_S3C64XX_DEV_SPI1 */
-
-#ifdef CONFIG_S3C64XX_DEV_SPI2
-static struct resource s3c64xx_spi2_resource[] = {
- [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256),
- [1] = DEFINE_RES_IRQ(IRQ_SPI2),
-};
-
-struct platform_device s3c64xx_device_spi2 = {
- .name = "s3c6410-spi",
- .id = 2,
- .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource),
- .resource = s3c64xx_spi2_resource,
- .dev = {
- .dma_mask = &samsung_device_dma_mask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
-
-void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
- int num_cs)
-{
- struct s3c64xx_spi_info pd;
-
- /* Reject invalid configuration */
- if (!num_cs || src_clk_nr < 0) {
- pr_err("%s: Invalid SPI configuration\n", __func__);
- return;
- }
-
- pd.num_cs = num_cs;
- pd.src_clk_nr = src_clk_nr;
- pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
-
- s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
-}
-#endif /* CONFIG_S3C64XX_DEV_SPI2 */
diff --git a/arch/arm/mach-s3c/mach-crag6410-module.c b/arch/arm/mach-s3c/mach-crag6410-module.c
index 407ad493493e..5d1d4b67a4b7 100644
--- a/arch/arm/mach-s3c/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c/mach-crag6410-module.c
@@ -32,10 +32,6 @@
#include "crag6410.h"
-static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
- .line = S3C64XX_GPC(3),
-};
-
static struct wm0010_pdata wm0010_pdata = {
.gpio_reset = S3C64XX_GPN(6),
.reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */
@@ -49,7 +45,6 @@ static struct spi_board_info wm1253_devs[] = {
.chip_select = 0,
.mode = SPI_MODE_0,
.irq = S3C_EINT(4),
- .controller_data = &wm0010_spi_csinfo,
.platform_data = &wm0010_pdata,
},
};
@@ -62,7 +57,6 @@ static struct spi_board_info balblair_devs[] = {
.chip_select = 0,
.mode = SPI_MODE_0,
.irq = S3C_EINT(4),
- .controller_data = &wm0010_spi_csinfo,
.platform_data = &wm0010_pdata,
},
};
@@ -229,10 +223,6 @@ static struct arizona_pdata wm5102_reva_pdata = {
},
};
-static struct s3c64xx_spi_csinfo codec_spi_csinfo = {
- .line = S3C64XX_GPN(5),
-};
-
static struct spi_board_info wm5102_reva_spi_devs[] = {
[0] = {
.modalias = "wm5102",
@@ -242,7 +232,6 @@ static struct spi_board_info wm5102_reva_spi_devs[] = {
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
- .controller_data = &codec_spi_csinfo,
.platform_data = &wm5102_reva_pdata,
},
};
@@ -275,7 +264,6 @@ static struct spi_board_info wm5102_spi_devs[] = {
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
- .controller_data = &codec_spi_csinfo,
.platform_data = &wm5102_pdata,
},
};
@@ -298,7 +286,6 @@ static struct spi_board_info wm5110_spi_devs[] = {
.mode = SPI_MODE_0,
.irq = GLENFARCLAS_PMIC_IRQ_BASE +
WM831X_IRQ_GPIO_2,
- .controller_data = &codec_spi_csinfo,
.platform_data = &wm5102_reva_pdata,
},
};
diff --git a/arch/arm/mach-s3c/mach-crag6410.c b/arch/arm/mach-s3c/mach-crag6410.c
index 4a12c75d407f..e3e0fe897bcc 100644
--- a/arch/arm/mach-s3c/mach-crag6410.c
+++ b/arch/arm/mach-s3c/mach-crag6410.c
@@ -825,6 +825,15 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
static struct dwc2_hsotg_plat crag6410_hsotg_pdata;
+static struct gpiod_lookup_table crag_spi0_gpiod_table = {
+ .dev_id = "s3c6410-spi.0",
+ .table = {
+ GPIO_LOOKUP_IDX("GPIOC", 3, "cs", 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX("GPION", 5, "cs", 1, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
static void __init crag6410_machine_init(void)
{
/* Open drain IRQs need pullups */
@@ -856,7 +865,9 @@ static void __init crag6410_machine_init(void)
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
samsung_keypad_set_platdata(&crag6410_keypad_data);
- s3c64xx_spi0_set_platdata(NULL, 0, 2);
+
+ gpiod_add_lookup_table(&crag_spi0_gpiod_table);
+ s3c64xx_spi0_set_platdata(0, 2);
pwm_add_table(crag6410_pwm_lookup, ARRAY_SIZE(crag6410_pwm_lookup));
platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
diff --git a/arch/arm/mach-s3c/setup-spi-s3c64xx.c b/arch/arm/mach-s3c/setup-spi-s3c64xx.c
index efcf78d41585..497aff71c29c 100644
--- a/arch/arm/mach-s3c/setup-spi-s3c64xx.c
+++ b/arch/arm/mach-s3c/setup-spi-s3c64xx.c
@@ -16,12 +16,3 @@ int s3c64xx_spi0_cfg_gpio(void)
return 0;
}
#endif
-
-#ifdef CONFIG_S3C64XX_DEV_SPI1
-int s3c64xx_spi1_cfg_gpio(void)
-{
- s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
- return 0;
-}
-#endif
diff --git a/arch/arm/mach-s3c/spi-core-s3c24xx.h b/arch/arm/mach-s3c/spi-core-s3c24xx.h
index 057667469cc3..919c5fd0c9af 100644
--- a/arch/arm/mach-s3c/spi-core-s3c24xx.h
+++ b/arch/arm/mach-s3c/spi-core-s3c24xx.h
@@ -16,12 +16,6 @@ static inline void s3c24xx_spi_setname(char *name)
#ifdef CONFIG_S3C64XX_DEV_SPI0
s3c64xx_device_spi0.name = name;
#endif
-#ifdef CONFIG_S3C64XX_DEV_SPI1
- s3c64xx_device_spi1.name = name;
-#endif
-#ifdef CONFIG_S3C64XX_DEV_SPI2
- s3c64xx_device_spi2.name = name;
-#endif
}
#endif /* __PLAT_S3C_SPI_CORE_S3C24XX_H */
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 3683d6f10973..50909c4b95b2 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
menuconfig ARCH_RENESAS
bool "Renesas ARM SoCs"
- depends on ARCH_MULTI_V7 && MMU
+ depends on ARCH_MULTI_V7
select ARM_GIC
select GPIOLIB
select NO_IOPORT_MAP
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 43ddec677c0b..594edf9bbea4 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -2,6 +2,7 @@
menuconfig ARCH_INTEL_SOCFPGA
bool "Altera SOCFPGA family"
depends on ARCH_MULTI_V7
+ select ARCH_HAS_RESET_CONTROLLER
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
select ARM_GIC
@@ -18,6 +19,7 @@ menuconfig ARCH_INTEL_SOCFPGA
select PL310_ERRATA_727915
select PL310_ERRATA_753970 if PL310
select PL310_ERRATA_769419
+ select RESET_CONTROLLER
if ARCH_INTEL_SOCFPGA
config SOCFPGA_SUSPEND
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index 74d1ca2a529a..b38391e9d8bf 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -29,7 +29,7 @@ void __init spear13xx_l2x0_init(void)
/*
* 512KB (64KB/way), 8-way associativity, parity supported
*
- * FIXME: 9th bit, of Auxillary Controller register must be set
+ * FIXME: 9th bit, of Auxiliary Controller register must be set
* for some spear13xx devices for stable L2 operation.
*
* Enable Early BRESP, L2 prefetch for Instruction and Data,
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 24ed7f4a87a4..c18def269137 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
menuconfig ARCH_U8500
bool "ST-Ericsson U8500 Series"
- depends on ARCH_MULTI_V7 && MMU
+ depends on ARCH_MULTI_V7
select AB8500_CORE
select ABX500_CORE
select ARM_AMBA
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 58afba346729..d30ee26ccc87 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -386,6 +386,7 @@ config CPU_V6
select CPU_PABRT_V6
select CPU_THUMB_CAPABLE
select CPU_TLB_V6 if MMU
+ select SMP_ON_UP if SMP
# ARMv6k
config CPU_V6K
@@ -830,6 +831,7 @@ config CPU_BPREDICT_DISABLE
config CPU_SPECTRE
bool
+ select GENERIC_CPU_VULNERABILITIES
config HARDEN_BRANCH_PREDICTOR
bool "Harden the branch predictor against aliasing attacks" if EXPERT
@@ -850,6 +852,16 @@ config HARDEN_BRANCH_PREDICTOR
If unsure, say Y.
+config HARDEN_BRANCH_HISTORY
+ bool "Harden Spectre style attacks against branch history" if EXPERT
+ depends on CPU_SPECTRE
+ default y
+ help
+ Speculation attacks against some high-performance processors can
+ make use of branch history to influence future speculation. When
+ taking an exception, a sequence of branches overwrites the branch
+ history, or branch history is invalidated.
+
config TLS_REG_EMUL
bool
select NEED_KUSER_HELPERS
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 830bbfb26ca5..7c9499b728c4 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -90,7 +90,7 @@ ENDPROC(v7_flush_icache_all)
*
* Flush the D-cache up to the Level of Unification Inner Shareable
*
- * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ * Corrupted registers: r0-r6, r9-r10
*/
ENTRY(v7_flush_dcache_louis)
@@ -117,7 +117,7 @@ ENDPROC(v7_flush_dcache_louis)
*
* Flush the whole D-cache.
*
- * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ * Corrupted registers: r0-r6, r9-r10
*
* - mm - mm_struct describing address space
*/
@@ -149,22 +149,22 @@ flush_levels:
movw r4, #0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
- movw r7, #0x7fff
- ands r7, r7, r1, lsr #13 @ extract max number of the index size
+ movw r6, #0x7fff
+ and r1, r6, r1, lsr #13 @ extract max number of the index size
+ mov r6, #1
+ movne r4, r4, lsl r5 @ # of ways shifted into bits [31:...]
+ movne r6, r6, lsl r5 @ 1 shifted left by same amount
loop1:
- mov r9, r7 @ create working copy of max index
+ mov r9, r1 @ create working copy of max index
loop2:
- ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11
- THUMB( lsl r6, r4, r5 )
- THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
- ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
- THUMB( lsl r6, r9, r2 )
- THUMB( orr r11, r11, r6 ) @ factor index number into r11
- mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
+ mov r5, r9, lsl r2 @ factor set number into r5
+ orr r5, r5, r4 @ factor way number into r5
+ orr r5, r5, r10 @ factor cache level into r5
+ mcr p15, 0, r5, c7, c14, 2 @ clean & invalidate by set/way
subs r9, r9, #1 @ decrement the index
bge loop2
- subs r4, r4, #1 @ decrement the way
- bge loop1
+ subs r4, r4, r6 @ decrement the way
+ bcs loop1
skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
@@ -192,14 +192,12 @@ ENDPROC(v7_flush_dcache_all)
*
*/
ENTRY(v7_flush_kern_cache_all)
- ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ stmfd sp!, {r4-r6, r9-r10, lr}
bl v7_flush_dcache_all
mov r0, #0
ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
- ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ ldmfd sp!, {r4-r6, r9-r10, lr}
ret lr
ENDPROC(v7_flush_kern_cache_all)
@@ -210,14 +208,12 @@ ENDPROC(v7_flush_kern_cache_all)
* Invalidate the I-cache to the point of unification.
*/
ENTRY(v7_flush_kern_cache_louis)
- ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ stmfd sp!, {r4-r6, r9-r10, lr}
bl v7_flush_dcache_louis
mov r0, #0
ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
- ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ ldmfd sp!, {r4-r6, r9-r10, lr}
ret lr
ENDPROC(v7_flush_kern_cache_louis)
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 48091870db89..4204ffa2d104 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -240,8 +240,7 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
unsigned int cpu = smp_processor_id();
u64 asid;
- if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
- __check_vmalloc_seq(mm);
+ check_vmalloc_seq(mm);
/*
* We cannot update the pgd and the ASID atomicly with classic
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 6d0cb0f7bc54..fe249ea91908 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -164,47 +164,6 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)
return phys;
}
-static void __init arm_initrd_init(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
- phys_addr_t start;
- unsigned long size;
-
- initrd_start = initrd_end = 0;
-
- if (!phys_initrd_size)
- return;
-
- /*
- * Round the memory region to page boundaries as per free_initrd_mem()
- * This allows us to detect whether the pages overlapping the initrd
- * are in use, but more importantly, reserves the entire set of pages
- * as we don't want these pages allocated for other purposes.
- */
- start = round_down(phys_initrd_start, PAGE_SIZE);
- size = phys_initrd_size + (phys_initrd_start - start);
- size = round_up(size, PAGE_SIZE);
-
- if (!memblock_is_region_memory(start, size)) {
- pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n",
- (u64)start, size);
- return;
- }
-
- if (memblock_is_region_reserved(start, size)) {
- pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n",
- (u64)start, size);
- return;
- }
-
- memblock_reserve(start, size);
-
- /* Now convert initrd to virtual addresses */
- initrd_start = __phys_to_virt(phys_initrd_start);
- initrd_end = initrd_start + phys_initrd_size;
-#endif
-}
-
#ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
void check_cpu_icache_size(int cpuid)
{
@@ -226,7 +185,7 @@ void __init arm_memblock_init(const struct machine_desc *mdesc)
/* Register the kernel text, kernel data and initrd with memblock. */
memblock_reserve(__pa(KERNEL_START), KERNEL_END - KERNEL_START);
- arm_initrd_init();
+ reserve_initrd_mem();
arm_mm_memblock_reserve();
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 197f8eb3a775..aa08bcb72db9 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -117,16 +117,21 @@ EXPORT_SYMBOL(ioremap_page);
void __check_vmalloc_seq(struct mm_struct *mm)
{
- unsigned int seq;
+ int seq;
do {
- seq = init_mm.context.vmalloc_seq;
+ seq = atomic_read(&init_mm.context.vmalloc_seq);
memcpy(pgd_offset(mm, VMALLOC_START),
pgd_offset_k(VMALLOC_START),
sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
pgd_index(VMALLOC_START)));
- mm->context.vmalloc_seq = seq;
- } while (seq != init_mm.context.vmalloc_seq);
+ /*
+ * Use a store-release so that other CPUs that observe the
+ * counter's new value are guaranteed to see the results of the
+ * memcpy as well.
+ */
+ atomic_set_release(&mm->context.vmalloc_seq, seq);
+ } while (seq != atomic_read(&init_mm.context.vmalloc_seq));
}
#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
@@ -157,7 +162,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
* Note: this is still racy on SMP machines.
*/
pmd_clear(pmdp);
- init_mm.context.vmalloc_seq++;
+ atomic_inc_return_release(&init_mm.context.vmalloc_seq);
/*
* Free the page table, if there was one.
@@ -174,8 +179,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
* Ensure that the active_mm is up to date - we want to
* catch any use-after-iounmap cases.
*/
- if (current->active_mm->context.vmalloc_seq != init_mm.context.vmalloc_seq)
- __check_vmalloc_seq(current->active_mm);
+ check_vmalloc_seq(current->active_mm);
flush_tlb_kernel_range(virt, end);
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 274e4f73fd33..5e2be37a198e 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -212,12 +212,14 @@ early_param("ecc", early_ecc);
static int __init early_cachepolicy(char *p)
{
pr_warn("cachepolicy kernel parameter not supported without cp15\n");
+ return 0;
}
early_param("cachepolicy", early_cachepolicy);
static int __init noalign_setup(char *__unused)
{
pr_warn("noalign kernel parameter not supported without cp15\n");
+ return 1;
}
__setup("noalign", noalign_setup);
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 114c05ab4dd9..06dbfb968182 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -6,8 +6,35 @@
#include <asm/cp15.h>
#include <asm/cputype.h>
#include <asm/proc-fns.h>
+#include <asm/spectre.h>
#include <asm/system_misc.h>
+#ifdef CONFIG_ARM_PSCI
+static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+
+ switch ((int)res.a0) {
+ case SMCCC_RET_SUCCESS:
+ return SPECTRE_MITIGATED;
+
+ case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED:
+ return SPECTRE_UNAFFECTED;
+
+ default:
+ return SPECTRE_VULNERABLE;
+ }
+}
+#else
+static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
+{
+ return SPECTRE_VULNERABLE;
+}
+#endif
+
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn);
@@ -36,13 +63,61 @@ static void __maybe_unused call_hvc_arch_workaround_1(void)
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
}
-static void cpu_v7_spectre_init(void)
+static unsigned int spectre_v2_install_workaround(unsigned int method)
{
const char *spectre_v2_method = NULL;
int cpu = smp_processor_id();
if (per_cpu(harden_branch_predictor_fn, cpu))
- return;
+ return SPECTRE_MITIGATED;
+
+ switch (method) {
+ case SPECTRE_V2_METHOD_BPIALL:
+ per_cpu(harden_branch_predictor_fn, cpu) =
+ harden_branch_predictor_bpiall;
+ spectre_v2_method = "BPIALL";
+ break;
+
+ case SPECTRE_V2_METHOD_ICIALLU:
+ per_cpu(harden_branch_predictor_fn, cpu) =
+ harden_branch_predictor_iciallu;
+ spectre_v2_method = "ICIALLU";
+ break;
+
+ case SPECTRE_V2_METHOD_HVC:
+ per_cpu(harden_branch_predictor_fn, cpu) =
+ call_hvc_arch_workaround_1;
+ cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
+ spectre_v2_method = "hypervisor";
+ break;
+
+ case SPECTRE_V2_METHOD_SMC:
+ per_cpu(harden_branch_predictor_fn, cpu) =
+ call_smc_arch_workaround_1;
+ cpu_do_switch_mm = cpu_v7_smc_switch_mm;
+ spectre_v2_method = "firmware";
+ break;
+ }
+
+ if (spectre_v2_method)
+ pr_info("CPU%u: Spectre v2: using %s workaround\n",
+ smp_processor_id(), spectre_v2_method);
+
+ return SPECTRE_MITIGATED;
+}
+#else
+static unsigned int spectre_v2_install_workaround(unsigned int method)
+{
+ pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n",
+ smp_processor_id());
+
+ return SPECTRE_VULNERABLE;
+}
+#endif
+
+static void cpu_v7_spectre_v2_init(void)
+{
+ unsigned int state, method = 0;
switch (read_cpuid_part()) {
case ARM_CPU_PART_CORTEX_A8:
@@ -51,69 +126,133 @@ static void cpu_v7_spectre_init(void)
case ARM_CPU_PART_CORTEX_A17:
case ARM_CPU_PART_CORTEX_A73:
case ARM_CPU_PART_CORTEX_A75:
- per_cpu(harden_branch_predictor_fn, cpu) =
- harden_branch_predictor_bpiall;
- spectre_v2_method = "BPIALL";
+ state = SPECTRE_MITIGATED;
+ method = SPECTRE_V2_METHOD_BPIALL;
break;
case ARM_CPU_PART_CORTEX_A15:
case ARM_CPU_PART_BRAHMA_B15:
- per_cpu(harden_branch_predictor_fn, cpu) =
- harden_branch_predictor_iciallu;
- spectre_v2_method = "ICIALLU";
+ state = SPECTRE_MITIGATED;
+ method = SPECTRE_V2_METHOD_ICIALLU;
break;
-#ifdef CONFIG_ARM_PSCI
case ARM_CPU_PART_BRAHMA_B53:
/* Requires no workaround */
+ state = SPECTRE_UNAFFECTED;
break;
+
default:
/* Other ARM CPUs require no workaround */
- if (read_cpuid_implementor() == ARM_CPU_IMP_ARM)
+ if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) {
+ state = SPECTRE_UNAFFECTED;
break;
+ }
+
fallthrough;
- /* Cortex A57/A72 require firmware workaround */
- case ARM_CPU_PART_CORTEX_A57:
- case ARM_CPU_PART_CORTEX_A72: {
- struct arm_smccc_res res;
- arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- if ((int)res.a0 != 0)
- return;
+ /* Cortex A57/A72 require firmware workaround */
+ case ARM_CPU_PART_CORTEX_A57:
+ case ARM_CPU_PART_CORTEX_A72:
+ state = spectre_v2_get_cpu_fw_mitigation_state();
+ if (state != SPECTRE_MITIGATED)
+ break;
switch (arm_smccc_1_1_get_conduit()) {
case SMCCC_CONDUIT_HVC:
- per_cpu(harden_branch_predictor_fn, cpu) =
- call_hvc_arch_workaround_1;
- cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
- spectre_v2_method = "hypervisor";
+ method = SPECTRE_V2_METHOD_HVC;
break;
case SMCCC_CONDUIT_SMC:
- per_cpu(harden_branch_predictor_fn, cpu) =
- call_smc_arch_workaround_1;
- cpu_do_switch_mm = cpu_v7_smc_switch_mm;
- spectre_v2_method = "firmware";
+ method = SPECTRE_V2_METHOD_SMC;
break;
default:
+ state = SPECTRE_VULNERABLE;
break;
}
}
-#endif
+
+ if (state == SPECTRE_MITIGATED)
+ state = spectre_v2_install_workaround(method);
+
+ spectre_v2_update_state(state, method);
+}
+
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+static int spectre_bhb_method;
+
+static const char *spectre_bhb_method_name(int method)
+{
+ switch (method) {
+ case SPECTRE_V2_METHOD_LOOP8:
+ return "loop";
+
+ case SPECTRE_V2_METHOD_BPIALL:
+ return "BPIALL";
+
+ default:
+ return "unknown";
}
+}
- if (spectre_v2_method)
- pr_info("CPU%u: Spectre v2: using %s workaround\n",
- smp_processor_id(), spectre_v2_method);
+static int spectre_bhb_install_workaround(int method)
+{
+ if (spectre_bhb_method != method) {
+ if (spectre_bhb_method) {
+ pr_err("CPU%u: Spectre BHB: method disagreement, system vulnerable\n",
+ smp_processor_id());
+
+ return SPECTRE_VULNERABLE;
+ }
+
+ if (spectre_bhb_update_vectors(method) == SPECTRE_VULNERABLE)
+ return SPECTRE_VULNERABLE;
+
+ spectre_bhb_method = method;
+ }
+
+ pr_info("CPU%u: Spectre BHB: using %s workaround\n",
+ smp_processor_id(), spectre_bhb_method_name(method));
+
+ return SPECTRE_MITIGATED;
}
#else
-static void cpu_v7_spectre_init(void)
+static int spectre_bhb_install_workaround(int method)
{
+ return SPECTRE_VULNERABLE;
}
#endif
+static void cpu_v7_spectre_bhb_init(void)
+{
+ unsigned int state, method = 0;
+
+ switch (read_cpuid_part()) {
+ case ARM_CPU_PART_CORTEX_A15:
+ case ARM_CPU_PART_BRAHMA_B15:
+ case ARM_CPU_PART_CORTEX_A57:
+ case ARM_CPU_PART_CORTEX_A72:
+ state = SPECTRE_MITIGATED;
+ method = SPECTRE_V2_METHOD_LOOP8;
+ break;
+
+ case ARM_CPU_PART_CORTEX_A73:
+ case ARM_CPU_PART_CORTEX_A75:
+ state = SPECTRE_MITIGATED;
+ method = SPECTRE_V2_METHOD_BPIALL;
+ break;
+
+ default:
+ state = SPECTRE_UNAFFECTED;
+ break;
+ }
+
+ if (state == SPECTRE_MITIGATED)
+ state = spectre_bhb_install_workaround(method);
+
+ spectre_v2_update_state(state, method);
+}
+
static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned,
u32 mask, const char *msg)
{
@@ -142,16 +281,17 @@ static bool check_spectre_auxcr(bool *warned, u32 bit)
void cpu_v7_ca8_ibe(void)
{
if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6)))
- cpu_v7_spectre_init();
+ cpu_v7_spectre_v2_init();
}
void cpu_v7_ca15_ibe(void)
{
if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0)))
- cpu_v7_spectre_init();
+ cpu_v7_spectre_v2_init();
}
void cpu_v7_bugs_init(void)
{
- cpu_v7_spectre_init();
+ cpu_v7_spectre_v2_init();
+ cpu_v7_spectre_bhb_init();
}
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 734f0be4f14a..3ef9ecdd6343 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -516,8 +516,7 @@ static void orion_gpio_mask_irq(struct irq_data *d)
irq_gc_unlock(gc);
}
-void __init orion_gpio_init(struct device_node *np,
- int gpio_base, int ngpio,
+void __init orion_gpio_init(int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
int secondary_irq_base,
int irqs[4])
@@ -545,9 +544,6 @@ void __init orion_gpio_init(struct device_node *np,
ochip->chip.base = gpio_base;
ochip->chip.ngpio = ngpio;
ochip->chip.can_sleep = 0;
-#ifdef CONFIG_OF
- ochip->chip.of_node = np;
-#endif
ochip->chip.dbg_show = orion_gpio_dbg_show;
spin_lock_init(&ochip->lock);
@@ -605,7 +601,7 @@ void __init orion_gpio_init(struct device_node *np,
IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
/* Setup irq domain on top of the generic chip. */
- ochip->domain = irq_domain_add_legacy(np,
+ ochip->domain = irq_domain_add_legacy(NULL,
ochip->chip.ngpio,
ochip->secondary_irq_base,
ochip->secondary_irq_base,
diff --git a/arch/arm/plat-orion/include/plat/orion-gpio.h b/arch/arm/plat-orion/include/plat/orion-gpio.h
index e856b073a9c8..25a2963e0e0f 100644
--- a/arch/arm/plat-orion/include/plat/orion-gpio.h
+++ b/arch/arm/plat-orion/include/plat/orion-gpio.h
@@ -30,8 +30,7 @@ int orion_gpio_led_blink_set(struct gpio_desc *desc, int state,
void orion_gpio_set_valid(unsigned pin, int mode);
/* Initialize gpiolib. */
-void __init orion_gpio_init(struct device_node *np,
- int gpio_base, int ngpio,
+void __init orion_gpio_init(int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
int secondary_irq_base,
int irq[4]);
diff --git a/arch/arm/probes/kprobes/actions-common.c b/arch/arm/probes/kprobes/actions-common.c
index 836aebe596cd..79171344dbeb 100644
--- a/arch/arm/probes/kprobes/actions-common.c
+++ b/arch/arm/probes/kprobes/actions-common.c
@@ -84,7 +84,8 @@ emulate_generic_r0_12_noflags(probes_opcode_t insn,
register void *rfn asm("lr") = asi->insn_fn;
__asm__ __volatile__ (
- "stmdb sp!, {%[regs], r11} \n\t"
+ARM( "stmdb sp!, {%[regs], r11} \n\t" )
+THUMB( "stmdb sp!, {%[regs], r7} \n\t" )
"ldmia %[regs], {r0-r12} \n\t"
#if __LINUX_ARM_ARCH__ >= 6
"blx %[fn] \n\t"
@@ -96,10 +97,11 @@ emulate_generic_r0_12_noflags(probes_opcode_t insn,
#endif
"ldr lr, [sp], #4 \n\t" /* lr = regs */
"stmia lr, {r0-r12} \n\t"
- "ldr r11, [sp], #4 \n\t"
+ARM( "ldr r11, [sp], #4 \n\t" )
+THUMB( "ldr r7, [sp], #4 \n\t" )
: [regs] "=r" (rregs), [fn] "=r" (rfn)
: "0" (rregs), "1" (rfn)
- : "r0", "r2", "r3", "r4", "r5", "r6", "r7",
+ : "r0", "r2", "r3", "r4", "r5", "r6", ARM("r7") THUMB("r11"),
"r8", "r9", "r10", "r12", "memory", "cc"
);
}
diff --git a/arch/arm/probes/kprobes/actions-thumb.c b/arch/arm/probes/kprobes/actions-thumb.c
index 7884fcb81c26..51624fc263fc 100644
--- a/arch/arm/probes/kprobes/actions-thumb.c
+++ b/arch/arm/probes/kprobes/actions-thumb.c
@@ -447,14 +447,16 @@ t16_emulate_loregs(probes_opcode_t insn,
__asm__ __volatile__ (
"msr cpsr_fs, %[oldcpsr] \n\t"
+ "mov r11, r7 \n\t"
"ldmia %[regs], {r0-r7} \n\t"
"blx %[fn] \n\t"
"stmia %[regs], {r0-r7} \n\t"
+ "mov r7, r11 \n\t"
"mrs %[newcpsr], cpsr \n\t"
: [newcpsr] "=r" (newcpsr)
: [oldcpsr] "r" (oldcpsr), [regs] "r" (regs),
[fn] "r" (asi->insn_fn)
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r11",
"lr", "memory", "cc"
);
@@ -524,14 +526,16 @@ t16_emulate_push(probes_opcode_t insn,
struct arch_probes_insn *asi, struct pt_regs *regs)
{
__asm__ __volatile__ (
+ "mov r11, r7 \n\t"
"ldr r9, [%[regs], #13*4] \n\t"
"ldr r8, [%[regs], #14*4] \n\t"
"ldmia %[regs], {r0-r7} \n\t"
"blx %[fn] \n\t"
"str r9, [%[regs], #13*4] \n\t"
+ "mov r7, r11 \n\t"
:
: [regs] "r" (regs), [fn] "r" (asi->insn_fn)
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r11",
"lr", "memory", "cc"
);
}
@@ -558,14 +562,16 @@ t16_emulate_pop_nopc(probes_opcode_t insn,
struct arch_probes_insn *asi, struct pt_regs *regs)
{
__asm__ __volatile__ (
+ "mov r11, r7 \n\t"
"ldr r9, [%[regs], #13*4] \n\t"
"ldmia %[regs], {r0-r7} \n\t"
"blx %[fn] \n\t"
"stmia %[regs], {r0-r7} \n\t"
"str r9, [%[regs], #13*4] \n\t"
+ "mov r7, r11 \n\t"
:
: [regs] "r" (regs), [fn] "r" (asi->insn_fn)
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r9", "r11",
"lr", "memory", "cc"
);
}
@@ -577,14 +583,16 @@ t16_emulate_pop_pc(probes_opcode_t insn,
register unsigned long pc asm("r8");
__asm__ __volatile__ (
+ "mov r11, r7 \n\t"
"ldr r9, [%[regs], #13*4] \n\t"
"ldmia %[regs], {r0-r7} \n\t"
"blx %[fn] \n\t"
"stmia %[regs], {r0-r7} \n\t"
"str r9, [%[regs], #13*4] \n\t"
+ "mov r7, r11 \n\t"
: "=r" (pc)
: [regs] "r" (regs), [fn] "r" (asi->insn_fn)
- : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
+ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r9", "r11",
"lr", "memory", "cc"
);
diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
index 7c9e395b77f7..ec52b776f926 100644
--- a/arch/arm/vdso/Makefile
+++ b/arch/arm/vdso/Makefile
@@ -18,7 +18,7 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO32
ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8
ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
- -z max-page-size=4096 -nostdlib -shared $(ldflags-y) \
+ -z max-page-size=4096 -shared $(ldflags-y) \
--hash-style=sysv --build-id=sha1 \
-T