diff options
Diffstat (limited to 'arch')
206 files changed, 1763 insertions, 884 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4f799e567fc8..2747202e3c4c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -547,6 +547,7 @@ config ARCH_PXA select CLKSRC_PXA select CLKSRC_MMIO select CLKSRC_OF + select CPU_XSCALE if !CPU_XSC3 select GENERIC_CLOCKEVENTS select GPIO_PXA select HAVE_IDE @@ -724,6 +725,8 @@ source "arch/arm/mach-mvebu/Kconfig" source "arch/arm/mach-alpine/Kconfig" +source "arch/arm/mach-artpec/Kconfig" + source "arch/arm/mach-asm9260/Kconfig" source "arch/arm/mach-at91/Kconfig" @@ -879,10 +882,16 @@ config ARCH_STM32 select ARCH_HAS_RESET_CONTROLLER select ARMV7M_SYSTICK select CLKSRC_STM32 + select PINCTRL select RESET_CONTROLLER help Support for STMicroelectronics STM32 processors. +config MACH_STM32F429 + bool "STMicrolectronics STM32F429" + depends on ARCH_STM32 + default y + # Definitions to make life easier config ARCH_ACORN bool diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index c6b6175d0203..1098e91d6d3f 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1368,6 +1368,7 @@ config DEBUG_SIRFSOC_UART config DEBUG_LL_INCLUDE string default "debug/sa1100.S" if DEBUG_SA1100 + default "debug/palmchip.S" if DEBUG_UART_8250_PALMCHIP default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 default "debug/at91.S" if DEBUG_AT91_UART default "debug/asm9260.S" if DEBUG_ASM9260_UART @@ -1656,6 +1657,14 @@ config DEBUG_UART_8250_WORD DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \ DEBUG_BRCMSTB_UART +config DEBUG_UART_8250_PALMCHIP + bool "8250 UART is Palmchip BK-310x" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + help + Palmchip provides a UART implementation compatible with 16550 + except for having a different register layout. Say Y here if + the debug UART is of this type. + config DEBUG_UART_8250_FLOW_CONTROL bool "Enable flow control for 8250 UART" depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index fe254108d1d9..4eb24c633714 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -154,6 +154,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. machine-$(CONFIG_ARCH_ALPINE) += alpine +machine-$(CONFIG_ARCH_ARTPEC) += artpec machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_AXXIA) += axxia machine-$(CONFIG_ARCH_BCM) += bcm diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 4c23a68a0917..7a6a58ef8aaf 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -106,6 +106,15 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) endif +# -fstack-protector-strong triggers protection checks in this code, +# but it is being used too early to link to meaningful stack_chk logic. +nossp_flags := $(call cc-option, -fno-stack-protector) +CFLAGS_atags_to_fdt.o := $(nossp_flags) +CFLAGS_fdt.o := $(nossp_flags) +CFLAGS_fdt_ro.o := $(nossp_flags) +CFLAGS_fdt_rw.o := $(nossp_flags) +CFLAGS_fdt_wip.o := $(nossp_flags) + ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj) asflags-y := -DZIMAGE diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 04885f9f959e..1fafaad516ba 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -439,6 +439,7 @@ ti,mbox-num-users = <4>; ti,mbox-num-fifos = <8>; mbox_wkupm3: wkup_m3 { + ti,mbox-send-noirq; ti,mbox-tx = <0 0 0>; ti,mbox-rx = <0 0 3>; }; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index df955ba4dc62..92068fbf8b57 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -73,7 +73,7 @@ global_timer: timer@48240200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x48240200 0x100>; - interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>; interrupt-parent = <&gic>; clocks = <&mpu_periphclk>; }; @@ -81,7 +81,7 @@ local_timer: timer@48240600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x48240600 0x100>; - interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_PPI 13 IRQ_TYPE_EDGE_RISING>; interrupt-parent = <&gic>; clocks = <&mpu_periphclk>; }; @@ -290,6 +290,7 @@ ti,mbox-num-users = <4>; ti,mbox-num-fifos = <8>; mbox_wkupm3: wkup_m3 { + ti,mbox-send-noirq; ti,mbox-tx = <0 0 0>; ti,mbox-rx = <0 0 3>; }; diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index 64d43325bcbc..ecd09ab6d581 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -590,8 +590,6 @@ pinctrl-names = "default"; pinctrl-0 = <&pixcir_ts_pins>; reg = <0x5c>; - interrupt-parent = <&gpio3>; - interrupts = <22 0>; attb-gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; @@ -599,7 +597,7 @@ * 0x264 represents the offset of padconf register of * gpio3_22 from am43xx_pinmux base. */ - interrupts-extended = <&gpio3 22 IRQ_TYPE_NONE>, + interrupts-extended = <&gpio3 22 IRQ_TYPE_EDGE_FALLING>, <&am43xx_pinmux 0x264>; interrupt-names = "tsc", "wakeup"; diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index 746fd2b17958..d580e2b70f9a 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -491,7 +491,7 @@ pinctrl-0 = <&pixcir_ts_pins>; reg = <0x5c>; interrupt-parent = <&gpio1>; - interrupts = <17 0>; + interrupts = <17 IRQ_TYPE_EDGE_FALLING>; attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts index c53882643ae9..8d93882dc8d5 100644 --- a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts +++ b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts @@ -167,7 +167,7 @@ DRA7XX_CORE_IOPAD(0x35b8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d20.rgmii1_rd3 */ DRA7XX_CORE_IOPAD(0x35bc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d21.rgmii1_rd2 */ DRA7XX_CORE_IOPAD(0x35c0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d22.rgmii1_rd1 */ - DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT_PULLUP | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */ + DRA7XX_CORE_IOPAD(0x35c4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* vin2a_d23.rgmii1_rd0 */ >; }; @@ -492,14 +492,14 @@ pinctrl-names = "default"; pinctrl-0 = <&qspi1_pins>; - spi-max-frequency = <20000000>; + spi-max-frequency = <48000000>; spi_flash: spi_flash@0 { #address-cells = <1>; #size-cells = <1>; compatible = "spansion,m25p80", "jedec,spi-nor"; reg = <0>; /* CS0 */ - spi-max-frequency = <20000000>; + spi-max-frequency = <48000000>; partition@0 { label = "uboot"; @@ -559,13 +559,13 @@ &cpsw_emac0 { phy_id = <&davinci_mdio>, <0>; - phy-mode = "rgmii"; + phy-mode = "rgmii-txid"; dual_emac_res_vlan = <0>; }; &cpsw_emac1 { phy_id = <&davinci_mdio>, <1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-txid"; dual_emac_res_vlan = <1>; }; @@ -588,7 +588,7 @@ }; &usb2 { - dr_mode = "peripheral"; + dr_mode = "host"; }; &mcasp3 { diff --git a/arch/arm/boot/dts/am57xx-sbc-am57x.dts b/arch/arm/boot/dts/am57xx-sbc-am57x.dts index 77bb8e17401a..988e99632d49 100644 --- a/arch/arm/boot/dts/am57xx-sbc-am57x.dts +++ b/arch/arm/boot/dts/am57xx-sbc-am57x.dts @@ -25,8 +25,8 @@ &dra7_pmx_core { uart3_pins_default: uart3_pins_default { pinctrl-single,pins = < - DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_SLEW | MUX_MODE2) /* uart2_ctsn.uart3_rxd */ - DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_SLEW | MUX_MODE1) /* uart2_rtsn.uart3_txd */ + DRA7XX_CORE_IOPAD(0x3648, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd */ + DRA7XX_CORE_IOPAD(0x364c, PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd */ >; }; @@ -108,9 +108,9 @@ pinctrl-0 = <&i2c5_pins_default>; clock-frequency = <400000>; - eeprom_base: atmel@50 { + eeprom_base: atmel@54 { compatible = "atmel,24c08"; - reg = <0x50>; + reg = <0x54>; pagesize = <16>; }; diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts index 13cf69a8d0fb..fb9e1bbf2338 100644 --- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts +++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts @@ -152,6 +152,7 @@ nand-on-flash-bbt; partitions { + compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index 77ddff036409..e683856c507c 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -114,9 +114,15 @@ macb0: ethernet@f8008000 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_macb0_default>; + pinctrl-0 = <&pinctrl_macb0_default &pinctrl_macb0_phy_irq>; phy-mode = "rmii"; status = "okay"; + + ethernet-phy@1 { + reg = <0x1>; + interrupt-parent = <&pioA>; + interrupts = <73 IRQ_TYPE_LEVEL_LOW>; + }; }; pdmic@f8018000 { @@ -300,6 +306,10 @@ bias-disable; }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = <PIN_PC9__GPIO>; + }; + pinctrl_pdmic_default: pdmic_default { pinmux = <PIN_PB26__PDMIC_DAT>, <PIN_PB27__PDMIC_CLK>; diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts index 131614f28e75..569026e8f96c 100644 --- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts @@ -86,10 +86,12 @@ macb0: ethernet@f8020000 { phy-mode = "rmii"; status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>; phy0: ethernet-phy@1 { interrupt-parent = <&pioE>; - interrupts = <1 IRQ_TYPE_EDGE_FALLING>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; reg = <1>; }; }; @@ -152,6 +154,10 @@ atmel,pins = <AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; }; + pinctrl_macb0_phy_irq: macb0_phy_irq_0 { + atmel,pins = + <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; }; }; }; diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index 2d4a33100af6..4e98cda97403 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -160,8 +160,15 @@ }; macb0: ethernet@f8020000 { + pinctrl-0 = <&pinctrl_macb0_rmii &pinctrl_macb0_phy_irq>; phy-mode = "rmii"; status = "okay"; + + ethernet-phy@1 { + reg = <0x1>; + interrupt-parent = <&pioE>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + }; }; mmc1: mmc@fc000000 { @@ -193,6 +200,10 @@ pinctrl@fc06a000 { board { + pinctrl_macb0_phy_irq: macb0_phy_irq { + atmel,pins = + <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; pinctrl_mmc0_cd: mmc0_cd { atmel,pins = <AT91_PIOE 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index ca4ddf86817a..626c67d66626 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -215,7 +215,7 @@ }; panel: panel { - compatible = "qd,qd43003c0-40", "simple-panel"; + compatible = "qiaodian,qd43003c0-40", "simple-panel"; backlight = <&backlight>; power-supply = <&panel_reg>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/kirkwood-lswvl.dts b/arch/arm/boot/dts/kirkwood-lswvl.dts index 09eed3cea0af..36eec7392ab4 100644 --- a/arch/arm/boot/dts/kirkwood-lswvl.dts +++ b/arch/arm/boot/dts/kirkwood-lswvl.dts @@ -1,7 +1,8 @@ /* * Device Tree file for Buffalo Linkstation LS-WVL/VL * - * Copyright (C) 2015, [email protected] + * Copyright (C) 2015, 2016 + * Roger Shimizu <[email protected]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -156,21 +157,21 @@ button@1 { label = "Function Button"; linux,code = <KEY_OPTION>; - gpios = <&gpio0 45 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; }; button@2 { label = "Power-on Switch"; linux,code = <KEY_RESERVED>; linux,input-type = <5>; - gpios = <&gpio0 46 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; }; button@3 { label = "Power-auto Switch"; linux,code = <KEY_ESC>; linux,input-type = <5>; - gpios = <&gpio0 47 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; }; @@ -185,38 +186,38 @@ led@1 { label = "lswvl:red:alarm"; - gpios = <&gpio0 36 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; }; led@2 { label = "lswvl:red:func"; - gpios = <&gpio0 37 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; }; led@3 { label = "lswvl:amber:info"; - gpios = <&gpio0 38 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; }; led@4 { label = "lswvl:blue:func"; - gpios = <&gpio0 39 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; }; led@5 { label = "lswvl:blue:power"; - gpios = <&gpio0 40 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; default-state = "keep"; }; led@6 { label = "lswvl:red:hdderr0"; - gpios = <&gpio0 34 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; }; led@7 { label = "lswvl:red:hdderr1"; - gpios = <&gpio0 35 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; }; }; @@ -233,7 +234,7 @@ 3250 1 5000 0>; - alarm-gpios = <&gpio0 43 GPIO_ACTIVE_HIGH>; + alarm-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; }; restart_poweroff { diff --git a/arch/arm/boot/dts/kirkwood-lswxl.dts b/arch/arm/boot/dts/kirkwood-lswxl.dts index f5db16a08597..b13ec20a7088 100644 --- a/arch/arm/boot/dts/kirkwood-lswxl.dts +++ b/arch/arm/boot/dts/kirkwood-lswxl.dts @@ -1,7 +1,8 @@ /* * Device Tree file for Buffalo Linkstation LS-WXL/WSXL * - * Copyright (C) 2015, [email protected] + * Copyright (C) 2015, 2016 + * Roger Shimizu <[email protected]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -156,21 +157,21 @@ button@1 { label = "Function Button"; linux,code = <KEY_OPTION>; - gpios = <&gpio1 41 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; }; button@2 { label = "Power-on Switch"; linux,code = <KEY_RESERVED>; linux,input-type = <5>; - gpios = <&gpio1 42 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; }; button@3 { label = "Power-auto Switch"; linux,code = <KEY_ESC>; linux,input-type = <5>; - gpios = <&gpio1 43 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; }; @@ -185,12 +186,12 @@ led@1 { label = "lswxl:blue:func"; - gpios = <&gpio1 36 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; }; led@2 { label = "lswxl:red:alarm"; - gpios = <&gpio1 49 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; led@3 { @@ -200,23 +201,23 @@ led@4 { label = "lswxl:blue:power"; - gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + default-state = "keep"; }; led@5 { label = "lswxl:red:func"; - gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; - default-state = "keep"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; }; led@6 { label = "lswxl:red:hdderr0"; - gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; + gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; }; led@7 { label = "lswxl:red:hdderr1"; - gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; }; }; @@ -225,15 +226,15 @@ pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; pinctrl-names = "default"; - gpios = <&gpio0 47 GPIO_ACTIVE_LOW - &gpio0 48 GPIO_ACTIVE_LOW>; + gpios = <&gpio1 16 GPIO_ACTIVE_LOW + &gpio1 15 GPIO_ACTIVE_LOW>; gpio-fan,speed-map = <0 3 1500 2 3250 1 5000 0>; - alarm-gpios = <&gpio1 49 GPIO_ACTIVE_HIGH>; + alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; }; restart_poweroff { @@ -256,7 +257,7 @@ enable-active-high; regulator-always-on; regulator-boot-on; - gpio = <&gpio0 37 GPIO_ACTIVE_HIGH>; + gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; }; hdd_power0: regulator@2 { compatible = "regulator-fixed"; diff --git a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts index 1db6f2c506cc..8082d64266a3 100644 --- a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts +++ b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts @@ -131,6 +131,7 @@ chip-delay = <40>; status = "okay"; partitions { + compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi index 7fed0bd4f3de..00805322367e 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi @@ -112,14 +112,6 @@ clock-frequency = <400000>; }; -&i2c2 { - clock-frequency = <400000>; -}; - -&i2c3 { - clock-frequency = <400000>; -}; - /* * Only found on the wireless SOM. For the SOM without wireless, the pins for * MMC3 can be routed with jumpers to the second MMC slot on the devkit and @@ -143,6 +135,7 @@ interrupt-parent = <&gpio5>; interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */ ref-clock-frequency = <26000000>; + tcxo-clock-frequency = <26000000>; }; }; diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index 888412c63f97..902657d6713b 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -130,6 +130,16 @@ }; }; +&gpio8 { + /* TI trees use GPIO instead of msecure, see also muxing */ + p234 { + gpio-hog; + gpios = <10 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "gpio8_234/msecure"; + }; +}; + &omap5_pmx_core { pinctrl-names = "default"; pinctrl-0 = < @@ -213,6 +223,13 @@ >; }; + /* TI trees use GPIO mode; msecure mode does not work reliably? */ + palmas_msecure_pins: palmas_msecure_pins { + pinctrl-single,pins = < + OMAP5_IOPAD(0x180, PIN_OUTPUT | MUX_MODE6) /* gpio8_234 */ + >; + }; + usbhost_pins: pinmux_usbhost_pins { pinctrl-single,pins = < OMAP5_IOPAD(0x0c4, PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */ @@ -278,6 +295,12 @@ &usbhost_wkup_pins >; + palmas_sys_nirq_pins: pinmux_palmas_sys_nirq_pins { + pinctrl-single,pins = < + OMAP5_IOPAD(0x068, PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1 */ + >; + }; + usbhost_wkup_pins: pinmux_usbhost_wkup_pins { pinctrl-single,pins = < OMAP5_IOPAD(0x05a, PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */ @@ -345,6 +368,8 @@ interrupt-controller; #interrupt-cells = <2>; ti,system-power-controller; + pinctrl-names = "default"; + pinctrl-0 = <&palmas_sys_nirq_pins &palmas_msecure_pins>; extcon_usb3: palmas_usb { compatible = "ti,palmas-usb-vid"; @@ -358,6 +383,14 @@ #clock-cells = <0>; }; + rtc { + compatible = "ti,palmas-rtc"; + interrupt-parent = <&palmas>; + interrupts = <8 IRQ_TYPE_NONE>; + ti,backup-battery-chargeable; + ti,backup-battery-charge-high-current; + }; + palmas_pmic { compatible = "ti,palmas-pmic"; interrupt-parent = <&palmas>; diff --git a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts index 3daec912b4bf..420788229e6f 100644 --- a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts +++ b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts @@ -1,7 +1,8 @@ /* * Device Tree file for Buffalo Linkstation LS-WTGL * - * Copyright (C) 2015, Roger Shimizu <[email protected]> + * Copyright (C) 2015, 2016 + * Roger Shimizu <[email protected]> * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -69,8 +70,6 @@ internal-regs { pinctrl: pinctrl@10000 { - pinctrl-0 = <&pmx_usb_power &pmx_power_hdd - &pmx_fan_low &pmx_fan_high &pmx_fan_lock>; pinctrl-names = "default"; pmx_led_power: pmx-leds { @@ -162,6 +161,7 @@ led@1 { label = "lswtgl:blue:power"; gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; led@2 { @@ -188,7 +188,7 @@ 3250 1 5000 0>; - alarm-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; }; restart_poweroff { diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi index 7f68a1ee7073..210192c38df3 100644 --- a/arch/arm/boot/dts/pxa27x.dtsi +++ b/arch/arm/boot/dts/pxa27x.dtsi @@ -13,6 +13,7 @@ interrupts = <25>; #dma-channels = <32>; #dma-cells = <2>; + #dma-requests = <75>; status = "okay"; }; diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi index cf6998a0804d..bea454f50ff9 100644 --- a/arch/arm/boot/dts/pxa3xx.dtsi +++ b/arch/arm/boot/dts/pxa3xx.dtsi @@ -12,6 +12,7 @@ interrupts = <25>; #dma-channels = <32>; #dma-cells = <2>; + #dma-requests = <100>; status = "okay"; }; diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index b8032bca4621..db1151c18466 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -1342,7 +1342,7 @@ dbgu: serial@fc069000 { compatible = "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"; reg = <0xfc069000 0x200>; - interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>; + interrupts = <45 IRQ_TYPE_LEVEL_HIGH 7>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_dbgu>; clocks = <&dbgu_clk>; diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index d0c743853318..27a333eb8987 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -127,22 +127,14 @@ }; mmcsd_default_mode: mmcsd_default { mmcsd_default_cfg1 { - /* MCCLK */ - pins = "GPIO8_B10"; - ste,output = <0>; - }; - mmcsd_default_cfg2 { - /* MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2 */ - pins = "GPIO10_C11", "GPIO15_A12", - "GPIO16_C13", "GPIO23_D15"; - ste,output = <1>; - }; - mmcsd_default_cfg3 { - /* MCCMD, MCDAT3-0, MCMSFBCLK */ - pins = "GPIO9_A10", "GPIO11_B11", - "GPIO12_A11", "GPIO13_C12", - "GPIO14_B12", "GPIO24_C15"; - ste,input = <1>; + /* + * MCCLK, MCCMDDIR, MCDAT0DIR, MCDAT31DIR, MCDATDIR2 + * MCCMD, MCDAT3-0, MCMSFBCLK + */ + pins = "GPIO8_B10", "GPIO9_A10", "GPIO10_C11", "GPIO11_B11", + "GPIO12_A11", "GPIO13_C12", "GPIO14_B12", "GPIO15_A12", + "GPIO16_C13", "GPIO23_D15", "GPIO24_C15"; + ste,output = <2>; }; }; }; @@ -802,10 +794,21 @@ clock-names = "mclk", "apb_pclk"; interrupt-parent = <&vica>; interrupts = <22>; - max-frequency = <48000000>; + max-frequency = <400000>; bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; + full-pwr-cycle; + /* + * The STw4811 circuit used with the Nomadik strictly + * requires that all of these signal direction pins be + * routed and used for its 4-bit levelshifter. + */ + st,sig-dir-dat0; + st,sig-dir-dat2; + st,sig-dir-dat31; + st,sig-dir-cmd; + st,sig-pin-fbclk; pinctrl-names = "default"; pinctrl-0 = <&mmcsd_default_mux>, <&mmcsd_default_mode>; vmmc-supply = <&vmmc_regulator>; diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 314f6be2dca2..8e8b2ace9b7c 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -426,6 +426,7 @@ CONFIG_SUNXI_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_TEGRA_WATCHDOG=m CONFIG_MESON_WATCHDOG=y +CONFIG_DW_WATCHDOG=y CONFIG_DIGICOLOR_WATCHDOG=y CONFIG_MFD_AS3711=y CONFIG_MFD_AS3722=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index c5e1943e5427..a7151744b85c 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -50,6 +50,7 @@ CONFIG_SOC_AM33XX=y CONFIG_SOC_AM43XX=y CONFIG_SOC_DRA7XX=y CONFIG_ARM_THUMBEE=y +CONFIG_ARM_KERNMEM_PERMS=y CONFIG_ARM_ERRATA_411920=y CONFIG_ARM_ERRATA_430973=y CONFIG_SMP=y @@ -177,6 +178,7 @@ CONFIG_TI_CPTS=y CONFIG_AT803X_PHY=y CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=m +CONFIG_USB_NET_SMSC75XX=m CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y @@ -354,6 +356,11 @@ CONFIG_USB_MUSB_DSPS=m CONFIG_USB_INVENTRA_DMA=y CONFIG_USB_TI_CPPI41_DMA=y CONFIG_USB_DWC3=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_TEST=m CONFIG_AM335X_PHY_USB=y CONFIG_USB_GADGET=m @@ -387,6 +394,7 @@ CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=m CONFIG_LEDS_GPIO=m CONFIG_LEDS_PWM=m +CONFIG_LEDS_PCA963X=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_ONESHOT=m @@ -449,6 +457,8 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_SPLIT=y +CONFIG_DEBUG_INFO_DWARF4=y CONFIG_MAGIC_SYSRQ=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 0cb724b5c639..dc5517eaf09f 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -378,6 +378,7 @@ CONFIG_GPIO_PALMAS=y CONFIG_GPIO_TPS6586X=y CONFIG_GPIO_TPS65910=y CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY_DEBUG=y CONFIG_PDA_POWER=m CONFIG_BATTERY_SBS=m diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S index 43243be94cfc..d4ae3b8e2426 100644 --- a/arch/arm/include/debug/at91.S +++ b/arch/arm/include/debug/at91.S @@ -15,7 +15,7 @@ #define AT91_IO_P2V(x) (x) #endif -#define CONFIG_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS) +#define AT91_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS) #define AT91_DBGU_SR (0x14) /* Status Register */ #define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ @@ -24,7 +24,7 @@ .macro addruart, rp, rv, tmp ldr \rp, =CONFIG_DEBUG_UART_PHYS @ System peripherals (phys address) - ldr \rv, =CONFIG_DEBUG_UART_VIRT @ System peripherals (virt address) + ldr \rv, =AT91_DEBUG_UART_VIRT @ System peripherals (virt address) .endm .macro senduart,rd,rx diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S index 619d8cc1ac12..92c44760d656 100644 --- a/arch/arm/include/debug/imx.S +++ b/arch/arm/include/debug/imx.S @@ -11,6 +11,7 @@ * */ +#include <asm/assembler.h> #include "imx-uart.h" /* @@ -34,6 +35,7 @@ .endm .macro senduart,rd,rx + ARM_BE8(rev \rd, \rd) str \rd, [\rx, #0x40] @ TXDATA .endm @@ -42,6 +44,7 @@ .macro busyuart,rd,rx 1002: ldr \rd, [\rx, #0x98] @ SR2 + ARM_BE8(rev \rd, \rd) tst \rd, #1 << 3 @ TXDC beq 1002b @ wait until transmit done .endm diff --git a/arch/arm/include/debug/palmchip.S b/arch/arm/include/debug/palmchip.S new file mode 100644 index 000000000000..6824b2d1c38e --- /dev/null +++ b/arch/arm/include/debug/palmchip.S @@ -0,0 +1,11 @@ +#include <linux/serial_reg.h> + +#undef UART_TX +#undef UART_LSR +#undef UART_MSR + +#define UART_TX 1 +#define UART_LSR 7 +#define UART_MSR 8 + +#include <debug/8250.S> diff --git a/arch/arm/include/debug/zynq.S b/arch/arm/include/debug/zynq.S index de86b9247564..060cb5b49bfd 100644 --- a/arch/arm/include/debug/zynq.S +++ b/arch/arm/include/debug/zynq.S @@ -20,9 +20,9 @@ #define UART_SR_TXEMPTY 0x00000008 /* TX FIFO empty */ #define UART0_PHYS 0xE0000000 -#define UART0_VIRT 0xF0000000 +#define UART0_VIRT 0xF0800000 #define UART1_PHYS 0xE0001000 -#define UART1_VIRT 0xF0001000 +#define UART1_VIRT 0xF0801000 #if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1) # define LL_UART_PADDR UART1_PHYS diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index ede692ffa32e..5dd2528e9e45 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h @@ -417,6 +417,7 @@ #define __NR_userfaultfd (__NR_SYSCALL_BASE+388) #define __NR_membarrier (__NR_SYSCALL_BASE+389) #define __NR_mlock2 (__NR_SYSCALL_BASE+390) +#define __NR_copy_file_range (__NR_SYSCALL_BASE+391) /* * The following SWIs are ARM private. diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index ac368bb068d1..dfc7cd6851ad 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -400,6 +400,7 @@ CALL(sys_userfaultfd) CALL(sys_membarrier) CALL(sys_mlock2) + CALL(sys_copy_file_range) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/arm/mach-alpine/Kconfig b/arch/arm/mach-alpine/Kconfig index 5c2d54f59f53..b41838a58ae4 100644 --- a/arch/arm/mach-alpine/Kconfig +++ b/arch/arm/mach-alpine/Kconfig @@ -1,6 +1,7 @@ config ARCH_ALPINE bool "Annapurna Labs Alpine platform" depends on ARCH_MULTI_V7 + select ALPINE_MSI select ARM_AMBA select ARM_GIC select GENERIC_IRQ_CHIP diff --git a/arch/arm/mach-artpec/Kconfig b/arch/arm/mach-artpec/Kconfig new file mode 100644 index 000000000000..6cbe5a2eabab --- /dev/null +++ b/arch/arm/mach-artpec/Kconfig @@ -0,0 +1,20 @@ +menuconfig ARCH_ARTPEC + bool "Axis Communications ARM based ARTPEC SoCs" + depends on ARCH_MULTI_V7 + +if ARCH_ARTPEC + +config MACH_ARTPEC6 + bool "Axis ARTPEC-6 ARM Cortex A9 Platform" + depends on ARCH_MULTI_V7 + select ARM_AMBA + select ARM_GIC + select ARM_GLOBAL_TIMER + select ARM_PSCI + select HAVE_ARM_ARCH_TIMER + select HAVE_ARM_SCU + select HAVE_ARM_TWD if SMP + help + Support for Axis ARTPEC-6 ARM Cortex A9 Platform + +endif diff --git a/arch/arm/mach-artpec/Makefile b/arch/arm/mach-artpec/Makefile new file mode 100644 index 000000000000..78325f0c859c --- /dev/null +++ b/arch/arm/mach-artpec/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MACH_ARTPEC6) := board-artpec6.o diff --git a/arch/arm/mach-artpec/board-artpec6.c b/arch/arm/mach-artpec/board-artpec6.c new file mode 100644 index 000000000000..71513df3374e --- /dev/null +++ b/arch/arm/mach-artpec/board-artpec6.c @@ -0,0 +1,72 @@ +/* + * ARTPEC-6 device support. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/amba/bus.h> +#include <linux/clocksource.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> +#include <linux/irqchip.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/mfd/syscon.h> +#include <linux/of_platform.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/smp.h> +#include <asm/smp_scu.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/psci.h> +#include <linux/arm-smccc.h> + + +#define ARTPEC6_DMACFG_REGNUM 0x10 +#define ARTPEC6_DMACFG_UARTS_BURST 0xff + +#define SECURE_OP_L2C_WRITEREG 0xb4000001 + +static void __init artpec6_init_machine(void) +{ + struct regmap *regmap; + + regmap = syscon_regmap_lookup_by_compatible("axis,artpec6-syscon"); + + if (!IS_ERR(regmap)) { + /* Use PL011 DMA Burst Request signal instead of DMA + * Single Request + */ + regmap_write(regmap, ARTPEC6_DMACFG_REGNUM, + ARTPEC6_DMACFG_UARTS_BURST); + }; + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static void artpec6_l2c310_write_sec(unsigned long val, unsigned reg) +{ + struct arm_smccc_res res; + + arm_smccc_smc(SECURE_OP_L2C_WRITEREG, reg, val, 0, + 0, 0, 0, 0, &res); + + WARN_ON(res.a0); +} + +static const char * const artpec6_dt_match[] = { + "axis,artpec6", + NULL +}; + +DT_MACHINE_START(ARTPEC6, "Axis ARTPEC-6 Platform") + .l2c_aux_val = 0x0C000000, + .l2c_aux_mask = 0xF3FFFFFF, + .l2c_write_sec = artpec6_l2c310_write_sec, + .init_machine = artpec6_init_machine, + .dt_compat = artpec6_dt_match, +MACHINE_END diff --git a/arch/arm/mach-bcm/bcm63xx_pmb.c b/arch/arm/mach-bcm/bcm63xx_pmb.c index de061ec5a479..41dcf5d65630 100644 --- a/arch/arm/mach-bcm/bcm63xx_pmb.c +++ b/arch/arm/mach-bcm/bcm63xx_pmb.c @@ -92,7 +92,6 @@ static int bcm63xx_pmb_get_resources(struct device_node *dn, unsigned int *cpu, unsigned int *addr) { - struct device_node *pmb_dn; struct of_phandle_args args; int ret; @@ -109,7 +108,6 @@ static int bcm63xx_pmb_get_resources(struct device_node *dn, return ret; } - pmb_dn = args.np; if (args.args_count != 2) { pr_err("reset-controller does not conform to reset-cells\n"); return -EINVAL; diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c index 575defcc53f9..cfae9c71fb74 100644 --- a/arch/arm/mach-bcm/platsmp.c +++ b/arch/arm/mach-bcm/platsmp.c @@ -283,7 +283,7 @@ static const struct smp_operations bcm_smp_ops __initconst = { CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", &bcm_smp_ops); -struct smp_operations nsp_smp_ops __initdata = { +static const struct smp_operations nsp_smp_ops __initconst = { .smp_prepare_cpus = bcm_smp_prepare_cpus, .smp_boot_secondary = nsp_boot_secondary, }; diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index e88b7a5cde99..725e693639d2 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -17,6 +17,7 @@ #include <linux/ahci_platform.h> #include <linux/clk.h> #include <linux/reboot.h> +#include <linux/dmaengine.h> #include <mach/cputype.h> #include <mach/common.h> @@ -233,16 +234,54 @@ static const struct platform_device_info da850_edma1_device __initconst = { .size_data = sizeof(da850_edma1_pdata), }; +static const struct dma_slave_map da830_edma_map[] = { + { "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 0) }, + { "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 1) }, + { "davinci-mcasp.1", "rx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcasp.1", "tx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci-mcasp.2", "rx", EDMA_FILTER_PARAM(0, 4) }, + { "davinci-mcasp.2", "tx", EDMA_FILTER_PARAM(0, 5) }, + { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 14) }, + { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 15) }, + { "da830-mmc.0", "rx", EDMA_FILTER_PARAM(0, 16) }, + { "da830-mmc.0", "tx", EDMA_FILTER_PARAM(0, 17) }, + { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 18) }, + { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 19) }, +}; + int __init da830_register_edma(struct edma_rsv_info *rsv) { struct platform_device *edma_pdev; da8xx_edma0_pdata.rsv = rsv; + da8xx_edma0_pdata.slave_map = da830_edma_map; + da8xx_edma0_pdata.slavecnt = ARRAY_SIZE(da830_edma_map); + edma_pdev = platform_device_register_full(&da8xx_edma0_device); return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0; } +static const struct dma_slave_map da850_edma0_map[] = { + { "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 0) }, + { "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 1) }, + { "davinci-mcbsp.0", "rx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp.0", "tx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci-mcbsp.1", "rx", EDMA_FILTER_PARAM(0, 4) }, + { "davinci-mcbsp.1", "tx", EDMA_FILTER_PARAM(0, 5) }, + { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 14) }, + { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 15) }, + { "da830-mmc.0", "rx", EDMA_FILTER_PARAM(0, 16) }, + { "da830-mmc.0", "tx", EDMA_FILTER_PARAM(0, 17) }, + { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 18) }, + { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 19) }, +}; + +static const struct dma_slave_map da850_edma1_map[] = { + { "da830-mmc.1", "rx", EDMA_FILTER_PARAM(1, 28) }, + { "da830-mmc.1", "tx", EDMA_FILTER_PARAM(1, 29) }, +}; + int __init da850_register_edma(struct edma_rsv_info *rsv[2]) { struct platform_device *edma_pdev; @@ -252,11 +291,18 @@ int __init da850_register_edma(struct edma_rsv_info *rsv[2]) da850_edma1_pdata.rsv = rsv[1]; } + da8xx_edma0_pdata.slave_map = da850_edma0_map; + da8xx_edma0_pdata.slavecnt = ARRAY_SIZE(da850_edma0_map); + edma_pdev = platform_device_register_full(&da8xx_edma0_device); if (IS_ERR(edma_pdev)) { pr_warn("%s: Failed to register eDMA0\n", __func__); return PTR_ERR(edma_pdev); } + + da850_edma1_pdata.slave_map = da850_edma1_map; + da850_edma1_pdata.slavecnt = ARRAY_SIZE(da850_edma1_map); + edma_pdev = platform_device_register_full(&da850_edma1_device); return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0; } diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index c7c1458df23c..a0ecf499c2f2 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -13,6 +13,7 @@ #include <linux/serial_8250.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/spi/spi.h> #include <linux/platform_data/edma.h> #include <linux/platform_data/gpio-davinci.h> @@ -576,9 +577,28 @@ static s8 queue_priority_mapping[][2] = { {-1, -1}, }; +static const struct dma_slave_map dm355_edma_map[] = { + { "davinci-mcbsp.0", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp.0", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci-mcbsp.1", "tx", EDMA_FILTER_PARAM(0, 8) }, + { "davinci-mcbsp.1", "rx", EDMA_FILTER_PARAM(0, 9) }, + { "spi_davinci.2", "tx", EDMA_FILTER_PARAM(0, 10) }, + { "spi_davinci.2", "rx", EDMA_FILTER_PARAM(0, 11) }, + { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 14) }, + { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 15) }, + { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 16) }, + { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 17) }, + { "dm6441-mmc.0", "rx", EDMA_FILTER_PARAM(0, 26) }, + { "dm6441-mmc.0", "tx", EDMA_FILTER_PARAM(0, 27) }, + { "dm6441-mmc.1", "rx", EDMA_FILTER_PARAM(0, 30) }, + { "dm6441-mmc.1", "tx", EDMA_FILTER_PARAM(0, 31) }, +}; + static struct edma_soc_info dm355_edma_pdata = { .queue_priority_mapping = queue_priority_mapping, .default_queue = EVENTQ_1, + .slave_map = dm355_edma_map, + .slavecnt = ARRAY_SIZE(dm355_edma_map), }; static struct resource edma_resources[] = { diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 01843fbcc9ea..384d3674dd9b 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -17,6 +17,7 @@ #include <linux/serial_8250.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/spi/spi.h> #include <linux/platform_data/edma.h> #include <linux/platform_data/gpio-davinci.h> @@ -862,9 +863,30 @@ static s8 dm365_queue_priority_mapping[][2] = { {-1, -1}, }; +static const struct dma_slave_map dm365_edma_map[] = { + { "davinci-mcbsp.0", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp.0", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci_voicecodec", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci_voicecodec", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "spi_davinci.2", "tx", EDMA_FILTER_PARAM(0, 10) }, + { "spi_davinci.2", "rx", EDMA_FILTER_PARAM(0, 11) }, + { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 14) }, + { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 15) }, + { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 16) }, + { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 17) }, + { "spi_davinci.3", "tx", EDMA_FILTER_PARAM(0, 18) }, + { "spi_davinci.3", "rx", EDMA_FILTER_PARAM(0, 19) }, + { "dm6441-mmc.0", "rx", EDMA_FILTER_PARAM(0, 26) }, + { "dm6441-mmc.0", "tx", EDMA_FILTER_PARAM(0, 27) }, + { "dm6441-mmc.1", "rx", EDMA_FILTER_PARAM(0, 30) }, + { "dm6441-mmc.1", "tx", EDMA_FILTER_PARAM(0, 31) }, +}; + static struct edma_soc_info dm365_edma_pdata = { .queue_priority_mapping = dm365_queue_priority_mapping, .default_queue = EVENTQ_3, + .slave_map = dm365_edma_map, + .slavecnt = ARRAY_SIZE(dm365_edma_map), }; static struct resource edma_resources[] = { diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index b28071ae3a57..b4b3a8b9ca20 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -11,6 +11,7 @@ #include <linux/init.h> #include <linux/clk.h> #include <linux/serial_8250.h> +#include <linux/dmaengine.h> #include <linux/platform_device.h> #include <linux/platform_data/edma.h> #include <linux/platform_data/gpio-davinci.h> @@ -505,9 +506,20 @@ static s8 queue_priority_mapping[][2] = { {-1, -1}, }; +static const struct dma_slave_map dm644x_edma_map[] = { + { "davinci-mcbsp", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "spi_davinci", "tx", EDMA_FILTER_PARAM(0, 16) }, + { "spi_davinci", "rx", EDMA_FILTER_PARAM(0, 17) }, + { "dm6441-mmc.0", "rx", EDMA_FILTER_PARAM(0, 26) }, + { "dm6441-mmc.0", "tx", EDMA_FILTER_PARAM(0, 27) }, +}; + static struct edma_soc_info dm644x_edma_pdata = { .queue_priority_mapping = queue_priority_mapping, .default_queue = EVENTQ_1, + .slave_map = dm644x_edma_map, + .slavecnt = ARRAY_SIZE(dm644x_edma_map), }; static struct resource edma_resources[] = { diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index cf80786e2471..a43db0f5fbaa 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -9,6 +9,7 @@ * or implied. */ #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/init.h> #include <linux/clk.h> #include <linux/serial_8250.h> @@ -540,9 +541,19 @@ static s8 dm646x_queue_priority_mapping[][2] = { {-1, -1}, }; +static const struct dma_slave_map dm646x_edma_map[] = { + { "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 6) }, + { "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 9) }, + { "davinci-mcasp.1", "tx", EDMA_FILTER_PARAM(0, 12) }, + { "spi_davinci", "tx", EDMA_FILTER_PARAM(0, 16) }, + { "spi_davinci", "rx", EDMA_FILTER_PARAM(0, 17) }, +}; + static struct edma_soc_info dm646x_edma_pdata = { .queue_priority_mapping = dm646x_queue_priority_mapping, .default_queue = EVENTQ_1, + .slave_map = dm646x_edma_map, + .slavecnt = ARRAY_SIZE(dm646x_edma_map), }; static struct resource edma_resources[] = { diff --git a/arch/arm/mach-imx/3ds_debugboard.c b/arch/arm/mach-imx/3ds_debugboard.c index 16496a071ecb..cda330c93d61 100644 --- a/arch/arm/mach-imx/3ds_debugboard.c +++ b/arch/arm/mach-imx/3ds_debugboard.c @@ -94,8 +94,8 @@ static void mxc_expio_irq_handler(struct irq_desc *desc) /* irq = gpio irq number */ desc->irq_data.chip->irq_mask(&desc->irq_data); - imr_val = __raw_readw(brd_io + INTR_MASK_REG); - int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; + imr_val = imx_readw(brd_io + INTR_MASK_REG); + int_valid = imx_readw(brd_io + INTR_STATUS_REG) & ~imr_val; expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { @@ -117,17 +117,17 @@ static void expio_mask_irq(struct irq_data *d) u16 reg; u32 expio = d->hwirq; - reg = __raw_readw(brd_io + INTR_MASK_REG); + reg = imx_readw(brd_io + INTR_MASK_REG); reg |= (1 << expio); - __raw_writew(reg, brd_io + INTR_MASK_REG); + imx_writew(reg, brd_io + INTR_MASK_REG); } static void expio_ack_irq(struct irq_data *d) { u32 expio = d->hwirq; - __raw_writew(1 << expio, brd_io + INTR_RESET_REG); - __raw_writew(0, brd_io + INTR_RESET_REG); + imx_writew(1 << expio, brd_io + INTR_RESET_REG); + imx_writew(0, brd_io + INTR_RESET_REG); expio_mask_irq(d); } @@ -136,9 +136,9 @@ static void expio_unmask_irq(struct irq_data *d) u16 reg; u32 expio = d->hwirq; - reg = __raw_readw(brd_io + INTR_MASK_REG); + reg = imx_readw(brd_io + INTR_MASK_REG); reg &= ~(1 << expio); - __raw_writew(reg, brd_io + INTR_MASK_REG); + imx_writew(reg, brd_io + INTR_MASK_REG); } static struct irq_chip expio_irq_chip = { @@ -162,9 +162,9 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) if (brd_io == NULL) return -ENOMEM; - if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || - (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || - (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { + if ((imx_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || + (imx_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || + (imx_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { pr_info("3-Stack Debug board not detected\n"); iounmap(brd_io); brd_io = NULL; @@ -181,10 +181,10 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) gpio_direction_input(intr_gpio); /* disable the interrupt and clear the status */ - __raw_writew(0, brd_io + INTR_MASK_REG); - __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); - __raw_writew(0, brd_io + INTR_RESET_REG); - __raw_writew(0x1F, brd_io + INTR_MASK_REG); + imx_writew(0, brd_io + INTR_MASK_REG); + imx_writew(0xFFFF, brd_io + INTR_RESET_REG); + imx_writew(0, brd_io + INTR_RESET_REG); + imx_writew(0x1F, brd_io + INTR_MASK_REG); irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); WARN_ON(irq_base < 0); diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 15df34fbdf44..8973fae25436 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -2,7 +2,7 @@ menuconfig ARCH_MXC bool "Freescale i.MX family" depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M select ARCH_REQUIRE_GPIOLIB - select ARM_CPU_SUSPEND if PM + select ARCH_SUPPORTS_BIG_ENDIAN select CLKSRC_IMX_GPT select GENERIC_IRQ_CHIP select PINCTRL @@ -511,6 +511,7 @@ config SOC_IMX53 config SOC_IMX6 bool + select ARM_CPU_SUSPEND if PM select ARM_ERRATA_754322 select ARM_ERRATA_775420 select ARM_GIC @@ -561,6 +562,7 @@ config SOC_IMX7D bool "i.MX7 Dual support" select PINCTRL_IMX7D select ARM_GIC + select HAVE_ARM_ARCH_TIMER select HAVE_IMX_ANATOP select HAVE_IMX_MMDC select HAVE_IMX_SRC diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index fb689d813b09..9fbe624a5ef9 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -3,7 +3,7 @@ obj-y := cpu.o system.o irq-common.o obj-$(CONFIG_SOC_IMX1) += mm-imx1.o obj-$(CONFIG_SOC_IMX21) += mm-imx21.o -obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o +obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o pm-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o obj-$(CONFIG_SOC_IMX27) += mm-imx27.o ehci-imx27.o diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 231bb250c571..649a84c251ad 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -129,7 +129,14 @@ void __init imx_init_revision_from_anatop(void) switch (digprog & 0xff) { case 0: - revision = IMX_CHIP_REVISION_1_0; + /* + * For i.MX6QP, most of the code for i.MX6Q can be resued, + * so internally, we identify it as i.MX6Q Rev 2.0 + */ + if (digprog >> 8 & 0x01) + revision = IMX_CHIP_REVISION_2_0; + else + revision = IMX_CHIP_REVISION_1_0; break; case 1: revision = IMX_CHIP_REVISION_1_1; @@ -151,7 +158,14 @@ void __init imx_init_revision_from_anatop(void) revision = IMX_CHIP_REVISION_1_5; break; default: - revision = IMX_CHIP_REVISION_UNKNOWN; + /* + * Fail back to return raw register value instead of 0xff. + * It will be easy to know version information in SOC if it + * can't be recognized by known version. And some chip's (i.MX7D) + * digprog value match linux version format, so it needn't map + * again and we can use register value directly. + */ + revision = digprog & 0xff; } mxc_set_cpu_type(digprog >> 16 & 0xff); diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 1a8932335b21..7fa176e792bd 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -66,12 +66,12 @@ static int avic_set_irq_fiq(unsigned int irq, unsigned int type) return -EINVAL; if (irq < AVIC_NUM_IRQS / 2) { - irqt = __raw_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); - __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); + irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); + imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); } else { irq -= AVIC_NUM_IRQS / 2; - irqt = __raw_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); - __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); + irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); + imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); } return 0; @@ -94,8 +94,8 @@ static void avic_irq_suspend(struct irq_data *d) struct irq_chip_type *ct = gc->chip_types; int idx = d->hwirq >> 5; - avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask); - __raw_writel(gc->wake_active, avic_base + ct->regs.mask); + avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask); + imx_writel(gc->wake_active, avic_base + ct->regs.mask); } static void avic_irq_resume(struct irq_data *d) @@ -104,7 +104,7 @@ static void avic_irq_resume(struct irq_data *d) struct irq_chip_type *ct = gc->chip_types; int idx = d->hwirq >> 5; - __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); + imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); } #else @@ -140,7 +140,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) u32 nivector; do { - nivector = __raw_readl(avic_base + AVIC_NIVECSR) >> 16; + nivector = imx_readl(avic_base + AVIC_NIVECSR) >> 16; if (nivector == 0xffff) break; @@ -164,16 +164,16 @@ void __init mxc_init_irq(void __iomem *irqbase) /* put the AVIC into the reset value with * all interrupts disabled */ - __raw_writel(0, avic_base + AVIC_INTCNTL); - __raw_writel(0x1f, avic_base + AVIC_NIMASK); + imx_writel(0, avic_base + AVIC_INTCNTL); + imx_writel(0x1f, avic_base + AVIC_NIMASK); /* disable all interrupts */ - __raw_writel(0, avic_base + AVIC_INTENABLEH); - __raw_writel(0, avic_base + AVIC_INTENABLEL); + imx_writel(0, avic_base + AVIC_INTENABLEH); + imx_writel(0, avic_base + AVIC_INTENABLEL); /* all IRQ no FIQ */ - __raw_writel(0, avic_base + AVIC_INTTYPEH); - __raw_writel(0, avic_base + AVIC_INTTYPEL); + imx_writel(0, avic_base + AVIC_INTTYPEH); + imx_writel(0, avic_base + AVIC_INTTYPEL); irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id()); WARN_ON(irq_base < 0); @@ -188,7 +188,7 @@ void __init mxc_init_irq(void __iomem *irqbase) /* Set default priority value (0) for all IRQ's */ for (i = 0; i < 8; i++) - __raw_writel(0, avic_base + AVIC_NIPRIORITY(i)); + imx_writel(0, avic_base + AVIC_NIPRIORITY(i)); set_handle_irq(avic_handle_irq); diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 32b83f09da18..58a38464480d 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -66,6 +66,7 @@ void imx_gpc_check_dt(void); void imx_gpc_set_arm_power_in_lpm(bool power_off); void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw); void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw); +void imx25_pm_init(void); enum mxc_cpu_pwr_mode { WAIT_CLOCKED, /* wfi only */ diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c index fe8d36f7e30e..8d2ae4091465 100644 --- a/arch/arm/mach-imx/cpu-imx27.c +++ b/arch/arm/mach-imx/cpu-imx27.c @@ -39,8 +39,7 @@ static int mx27_read_cpu_rev(void) * the silicon revision very early we read it here to * avoid any further hooks */ - val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR - + SYS_CHIP_ID)); + val = imx_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR + SYS_CHIP_ID)); mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c index fde1860a2521..3daf1959a2f0 100644 --- a/arch/arm/mach-imx/cpu-imx31.c +++ b/arch/arm/mach-imx/cpu-imx31.c @@ -39,7 +39,7 @@ static int mx31_read_cpu_rev(void) u32 i, srev; /* read SREV register from IIM module */ - srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); + srev = imx_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); srev &= 0xff; for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c index ec3aaa098c17..8a54234df23b 100644 --- a/arch/arm/mach-imx/cpu-imx35.c +++ b/arch/arm/mach-imx/cpu-imx35.c @@ -20,7 +20,7 @@ static int mx35_read_cpu_rev(void) { u32 rev; - rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); + rev = imx_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); switch (rev) { case 0x00: return IMX_CHIP_REVISION_1_0; diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 5b0f752d5507..6a96b7cf468f 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -45,20 +45,20 @@ void __init imx_set_aips(void __iomem *base) * Set all MPROTx to be non-bufferable, trusted for R/W, * not forced to user-mode. */ - __raw_writel(0x77777777, base + 0x0); - __raw_writel(0x77777777, base + 0x4); + imx_writel(0x77777777, base + 0x0); + imx_writel(0x77777777, base + 0x4); /* * Set all OPACRx to be non-bufferable, to not require * supervisor privilege level for access, allow for * write access and untrusted master access. */ - __raw_writel(0x0, base + 0x40); - __raw_writel(0x0, base + 0x44); - __raw_writel(0x0, base + 0x48); - __raw_writel(0x0, base + 0x4C); - reg = __raw_readl(base + 0x50) & 0x00FFFFFF; - __raw_writel(reg, base + 0x50); + imx_writel(0x0, base + 0x40); + imx_writel(0x0, base + 0x44); + imx_writel(0x0, base + 0x48); + imx_writel(0x0, base + 0x4C); + reg = imx_readl(base + 0x50) & 0x00FFFFFF; + imx_writel(reg, base + 0x50); } void __init imx_aips_allow_unprivileged_access( diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c index 08ce20771bb3..fb9a73a57d00 100644 --- a/arch/arm/mach-imx/epit.c +++ b/arch/arm/mach-imx/epit.c @@ -64,23 +64,23 @@ static inline void epit_irq_disable(void) { u32 val; - val = __raw_readl(timer_base + EPITCR); + val = imx_readl(timer_base + EPITCR); val &= ~EPITCR_OCIEN; - __raw_writel(val, timer_base + EPITCR); + imx_writel(val, timer_base + EPITCR); } static inline void epit_irq_enable(void) { u32 val; - val = __raw_readl(timer_base + EPITCR); + val = imx_readl(timer_base + EPITCR); val |= EPITCR_OCIEN; - __raw_writel(val, timer_base + EPITCR); + imx_writel(val, timer_base + EPITCR); } static void epit_irq_acknowledge(void) { - __raw_writel(EPITSR_OCIF, timer_base + EPITSR); + imx_writel(EPITSR_OCIF, timer_base + EPITSR); } static int __init epit_clocksource_init(struct clk *timer_clk) @@ -98,9 +98,9 @@ static int epit_set_next_event(unsigned long evt, { unsigned long tcmp; - tcmp = __raw_readl(timer_base + EPITCNR); + tcmp = imx_readl(timer_base + EPITCNR); - __raw_writel(tcmp - evt, timer_base + EPITCMPR); + imx_writel(tcmp - evt, timer_base + EPITCMPR); return 0; } @@ -213,11 +213,11 @@ void __init epit_timer_init(void __iomem *base, int irq) /* * Initialise to a known state (all timers off, and timing reset) */ - __raw_writel(0x0, timer_base + EPITCR); + imx_writel(0x0, timer_base + EPITCR); - __raw_writel(0xffffffff, timer_base + EPITLR); - __raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, - timer_base + EPITCR); + imx_writel(0xffffffff, timer_base + EPITLR); + imx_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, + timer_base + EPITCR); /* init and register the timer to the framework */ epit_clocksource_init(timer_clk); diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index b5e976816b63..6c28d28b3c64 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S @@ -12,6 +12,7 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <asm/assembler.h> diag_reg_offset: .word g_diag_reg - . @@ -25,6 +26,7 @@ diag_reg_offset: .endm ENTRY(v7_secondary_startup) +ARM_BE8(setend be) @ go BE8 if entered LE set_diag_reg b secondary_startup ENDPROC(v7_secondary_startup) diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c index 0b5ba4bf572a..3982e91b2f3e 100644 --- a/arch/arm/mach-imx/iomux-imx31.c +++ b/arch/arm/mach-imx/iomux-imx31.c @@ -57,10 +57,10 @@ void mxc_iomux_mode(unsigned int pin_mode) spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); + l = imx_readl(reg); l &= ~(0xff << (field * 8)); l |= mode << (field * 8); - __raw_writel(l, reg); + imx_writel(l, reg); spin_unlock(&gpio_mux_lock); } @@ -82,10 +82,10 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); + l = imx_readl(reg); l &= ~(0x1ff << (field * 10)); l |= config << (field * 10); - __raw_writel(l, reg); + imx_writel(l, reg); spin_unlock(&gpio_mux_lock); } @@ -163,12 +163,12 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) u32 l; spin_lock(&gpio_mux_lock); - l = __raw_readl(IOMUXGPR); + l = imx_readl(IOMUXGPR); if (en) l |= gp; else l &= ~gp; - __raw_writel(l, IOMUXGPR); + imx_writel(l, IOMUXGPR); spin_unlock(&gpio_mux_lock); } diff --git a/arch/arm/mach-imx/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c index ecd543664644..7aa90c863ad9 100644 --- a/arch/arm/mach-imx/iomux-v1.c +++ b/arch/arm/mach-imx/iomux-v1.c @@ -38,12 +38,12 @@ static unsigned imx_iomuxv1_numports; static inline unsigned long imx_iomuxv1_readl(unsigned offset) { - return __raw_readl(imx_iomuxv1_baseaddr + offset); + return imx_readl(imx_iomuxv1_baseaddr + offset); } static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset) { - __raw_writel(val, imx_iomuxv1_baseaddr + offset); + imx_writel(val, imx_iomuxv1_baseaddr + offset); } static inline void imx_iomuxv1_rmwl(unsigned offset, diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c index a53b2e64f98d..ca59d5f2ec92 100644 --- a/arch/arm/mach-imx/iomux-v3.c +++ b/arch/arm/mach-imx/iomux-v3.c @@ -45,13 +45,13 @@ int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad) u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; if (mux_ctrl_ofs) - __raw_writel(mux_mode, base + mux_ctrl_ofs); + imx_writel(mux_mode, base + mux_ctrl_ofs); if (sel_input_ofs) - __raw_writel(sel_input, base + sel_input_ofs); + imx_writel(sel_input, base + sel_input_ofs); if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs) - __raw_writel(pad_ctrl, base + pad_ctrl_ofs); + imx_writel(pad_ctrl, base + pad_ctrl_ofs); return 0; } diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index f2060523ba48..eaee47a2fcc0 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -525,8 +525,8 @@ static void __init armadillo5x0_init(void) imx31_add_mxc_nand(&armadillo5x0_nand_board_info); /* set NAND page size to 2k if not configured via boot mode pins */ - __raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) | - (1 << 30), mx3_ccm_base + MXC_CCM_RCSR); + imx_writel(imx_readl(mx3_ccm_base + MXC_CCM_RCSR) | (1 << 30), + mx3_ccm_base + MXC_CCM_RCSR); /* RTC */ /* Get RTC IRQ and register the chip */ diff --git a/arch/arm/mach-imx/mach-imx25.c b/arch/arm/mach-imx/mach-imx25.c index 9379fd0a7b4d..32dcb5e99e23 100644 --- a/arch/arm/mach-imx/mach-imx25.c +++ b/arch/arm/mach-imx/mach-imx25.c @@ -41,6 +41,7 @@ static const char * const imx25_dt_board_compat[] __initconst = { DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)") .init_early = imx25_init_early, + .init_late = imx25_pm_init, .init_irq = mx25_init_irq, .dt_compat = imx25_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-imx/mach-imx51.c b/arch/arm/mach-imx/mach-imx51.c index b015129e4045..6883fbaf9484 100644 --- a/arch/arm/mach-imx/mach-imx51.c +++ b/arch/arm/mach-imx/mach-imx51.c @@ -40,11 +40,10 @@ static void __init imx51_ipu_mipi_setup(void) WARN_ON(!hsc_addr); /* setup MIPI module to legacy mode */ - __raw_writel(0xf00, hsc_addr); + imx_writel(0xf00, hsc_addr); /* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */ - __raw_writel(__raw_readl(hsc_addr + 0x800) | 0x30ff, - hsc_addr + 0x800); + imx_writel(imx_readl(hsc_addr + 0x800) | 0x30ff, hsc_addr + 0x800); iounmap(hsc_addr); } diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 3878494bd118..cb27d566d5ab 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -266,8 +266,11 @@ static void __init imx6q_init_machine(void) { struct device *parent; - imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", - imx_get_soc_revision()); + if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0) + imx_print_silicon_rev("i.MX6QP", IMX_CHIP_REVISION_1_0); + else + imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", + imx_get_soc_revision()); parent = imx_soc_device_init(); if (parent == NULL) @@ -399,6 +402,7 @@ static void __init imx6q_init_irq(void) static const char * const imx6q_dt_compat[] __initconst = { "fsl,imx6dl", "fsl,imx6q", + "fsl,imx6qp", NULL, }; diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c index eb1c3477c48a..267fad23b225 100644 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ b/arch/arm/mach-imx/mach-mx27ads.c @@ -202,9 +202,9 @@ static struct i2c_board_info mx27ads_i2c_devices[] = { static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value) { if (value) - __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); + imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); else - __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); + imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); } static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) @@ -364,7 +364,7 @@ static void __init mx27ads_timer_init(void) { unsigned long fref = 26000000; - if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) + if ((imx_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) fref = 27000000; mx27_clocks_init(fref); diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 2b147e4bf9c9..4f2c56d44ba1 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -160,8 +160,8 @@ static void mx31ads_expio_irq_handler(struct irq_desc *desc) u32 int_valid; u32 expio_irq; - imr_val = __raw_readw(PBC_INTMASK_SET_REG); - int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; + imr_val = imx_readw(PBC_INTMASK_SET_REG); + int_valid = imx_readw(PBC_INTSTATUS_REG) & imr_val; expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { @@ -180,8 +180,8 @@ static void expio_mask_irq(struct irq_data *d) { u32 expio = d->hwirq; /* mask the interrupt */ - __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); - __raw_readw(PBC_INTMASK_CLEAR_REG); + imx_writew(1 << expio, PBC_INTMASK_CLEAR_REG); + imx_readw(PBC_INTMASK_CLEAR_REG); } /* @@ -192,7 +192,7 @@ static void expio_ack_irq(struct irq_data *d) { u32 expio = d->hwirq; /* clear the interrupt status */ - __raw_writew(1 << expio, PBC_INTSTATUS_REG); + imx_writew(1 << expio, PBC_INTSTATUS_REG); } /* @@ -203,7 +203,7 @@ static void expio_unmask_irq(struct irq_data *d) { u32 expio = d->hwirq; /* unmask the interrupt */ - __raw_writew(1 << expio, PBC_INTMASK_SET_REG); + imx_writew(1 << expio, PBC_INTMASK_SET_REG); } static struct irq_chip expio_irq_chip = { @@ -226,8 +226,8 @@ static void __init mx31ads_init_expio(void) mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio"); /* disable the interrupt and clear the status */ - __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); - __raw_writew(0xFFFF, PBC_INTSTATUS_REG); + imx_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); + imx_writew(0xFFFF, PBC_INTSTATUS_REG); irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); WARN_ON(irq_base < 0); diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index bb6f8a52a6b8..4f2d99888afd 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -509,7 +509,7 @@ static void mx31moboard_poweroff(void) mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST); - __raw_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); + imx_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); } static int mx31moboard_baseboard; diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index 5c2764604727..34df64f133ed 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -190,9 +190,9 @@ static struct platform_device qong_nand_device = { static void __init qong_init_nand_mtd(void) { /* init CS */ - __raw_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); - __raw_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); - __raw_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); + imx_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); + imx_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); + imx_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true); diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index a5b1af6d7441..d32704256781 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -193,4 +193,9 @@ extern struct cpu_op *(*get_cpu_op)(int *op); #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) +#define imx_readl readl_relaxed +#define imx_readw readw_relaxed +#define imx_writel writel_relaxed +#define imx_writew writew_relaxed + #endif /* __ASM_ARCH_MXC_H__ */ diff --git a/arch/arm/mach-imx/pm-imx25.c b/arch/arm/mach-imx/pm-imx25.c new file mode 100644 index 000000000000..8bba9fcd96f6 --- /dev/null +++ b/arch/arm/mach-imx/pm-imx25.c @@ -0,0 +1,37 @@ +/* + * Copyright 2016 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/suspend.h> +#include <linux/io.h> + +static int imx25_suspend_enter(suspend_state_t state) +{ + if (!IS_ENABLED(CONFIG_PM)) + return 0; + + switch (state) { + case PM_SUSPEND_MEM: + cpu_do_idle(); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct platform_suspend_ops imx25_suspend_ops = { + .enter = imx25_suspend_enter, + .valid = suspend_valid_only_mem, +}; + +void __init imx25_pm_init(void) +{ + suspend_set_ops(&imx25_suspend_ops); +} diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index 56d02d064fbf..43096c8990d4 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c @@ -19,9 +19,9 @@ static int mx27_suspend_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: /* Clear MPEN and SPEN to disable MPLL/SPLL */ - cscr = __raw_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + cscr = imx_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); cscr &= 0xFFFFFFFC; - __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + imx_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); /* Executes WFI */ cpu_do_idle(); break; diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c index 6a07006ff0f4..94c0898751d8 100644 --- a/arch/arm/mach-imx/pm-imx3.c +++ b/arch/arm/mach-imx/pm-imx3.c @@ -22,14 +22,14 @@ */ void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode) { - int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR); + int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR); reg &= ~MXC_CCM_CCMR_LPM_MASK; switch (mode) { case MX3_WAIT: if (cpu_is_mx35()) reg |= MXC_CCM_CCMR_LPM_WAIT_MX35; - __raw_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); + imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); break; default: pr_err("Unknown cpu power mode: %d\n", mode); diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index 532d4b08276d..868781fd460c 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -153,15 +153,15 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) int stop_mode = 0; /* always allow platform to issue a deep sleep mode request */ - plat_lpc = __raw_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & + plat_lpc = imx_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & ~(MXC_CORTEXA8_PLAT_LPC_DSM); - ccm_clpcr = __raw_readl(ccm_base + MXC_CCM_CLPCR) & + ccm_clpcr = imx_readl(ccm_base + MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); - arm_srpgcr = __raw_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & + arm_srpgcr = imx_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); - empgc0 = __raw_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & + empgc0 = imx_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); - empgc1 = __raw_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & + empgc1 = imx_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); switch (mode) { @@ -196,17 +196,17 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) return; } - __raw_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); - __raw_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); - __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); - __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); + imx_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); + imx_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); + imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); + imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); if (stop_mode) { empgc0 |= MXC_SRPGCR_PCR; empgc1 |= MXC_SRPGCR_PCR; - __raw_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + imx_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); + imx_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); } } @@ -228,8 +228,8 @@ static int mx5_suspend_enter(suspend_state_t state) flush_cache_all(); /*clear the EMPGC0/1 bits */ - __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + imx_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); + imx_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); if (imx5_suspend_in_ocram_fn) imx5_suspend_in_ocram_fn(suspend_ocram_base); diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 4470376af5f8..58924b3844df 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -561,13 +561,13 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) goto put_node; pl310_cache_map_failed: - iounmap(&pm_info->gpc_base.vbase); + iounmap(pm_info->gpc_base.vbase); gpc_map_failed: - iounmap(&pm_info->iomuxc_base.vbase); + iounmap(pm_info->iomuxc_base.vbase); iomuxc_map_failed: - iounmap(&pm_info->src_base.vbase); + iounmap(pm_info->src_base.vbase); src_map_failed: - iounmap(&pm_info->mmdc_base.vbase); + iounmap(pm_info->mmdc_base.vbase); put_node: of_node_put(node); diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index 45f7f4e0a447..70b083fe934a 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -73,7 +73,7 @@ static int imx_src_reset_module(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops imx_src_ops = { +static const struct reset_control_ops imx_src_ops = { .reset = imx_src_reset_module, }; diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index 51c35013b673..105d1ce4ed9d 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c @@ -54,7 +54,7 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) wcr_enable = (1 << 2); /* Assert SRS signal */ - __raw_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); /* * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be * written twice), we add another two writes to ensure there must be at @@ -62,8 +62,8 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) * the target check here, since the writes shouldn't be a huge burden * for other platforms. */ - __raw_writew(wcr_enable, wdog_base); - __raw_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); /* wait for reset to assert... */ mdelay(500); @@ -106,6 +106,9 @@ void __init imx_init_l2cache(void) goto out; } + if (readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN) + goto skip_if_enabled; + /* Configure the L2 PREFETCH and POWER registers */ val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL); val |= 0x70800000; @@ -122,6 +125,7 @@ void __init imx_init_l2cache(void) val &= ~(1 << 30 | 1 << 23); writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL); +skip_if_enabled: iounmap(l2x0_base); of_node_put(np); diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c index 4de65eeda1eb..ae23d50f7861 100644 --- a/arch/arm/mach-imx/tzic.c +++ b/arch/arm/mach-imx/tzic.c @@ -65,10 +65,10 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) return -EINVAL; mask = 1U << (irq & 0x1F); - value = __raw_readl(tzic_base + TZIC_INTSEC0(index)) | mask; + value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask; if (type) value &= ~mask; - __raw_writel(value, tzic_base + TZIC_INTSEC0(index)); + imx_writel(value, tzic_base + TZIC_INTSEC0(index)); return 0; } @@ -82,15 +82,15 @@ static void tzic_irq_suspend(struct irq_data *d) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); int idx = d->hwirq >> 5; - __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); + imx_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); } static void tzic_irq_resume(struct irq_data *d) { int idx = d->hwirq >> 5; - __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)), - tzic_base + TZIC_WAKEUP0(idx)); + imx_writel(imx_readl(tzic_base + TZIC_ENSET0(idx)), + tzic_base + TZIC_WAKEUP0(idx)); } #else @@ -135,8 +135,8 @@ static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) handled = 0; for (i = 0; i < 4; i++) { - stat = __raw_readl(tzic_base + TZIC_HIPND(i)) & - __raw_readl(tzic_base + TZIC_INTSEC0(i)); + stat = imx_readl(tzic_base + TZIC_HIPND(i)) & + imx_readl(tzic_base + TZIC_INTSEC0(i)); while (stat) { handled = 1; @@ -166,18 +166,18 @@ void __init tzic_init_irq(void) /* put the TZIC into the reset value with * all interrupts disabled */ - i = __raw_readl(tzic_base + TZIC_INTCNTL); + i = imx_readl(tzic_base + TZIC_INTCNTL); - __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL); - __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK); - __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL); + imx_writel(0x80010001, tzic_base + TZIC_INTCNTL); + imx_writel(0x1f, tzic_base + TZIC_PRIOMASK); + imx_writel(0x02, tzic_base + TZIC_SYNCCTRL); for (i = 0; i < 4; i++) - __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); + imx_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); /* disable all interrupts */ for (i = 0; i < 4; i++) - __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i)); + imx_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i)); /* all IRQ no FIQ Warning :: No selection */ @@ -214,13 +214,13 @@ int tzic_enable_wake(void) { unsigned int i; - __raw_writel(1, tzic_base + TZIC_DSMINT); - if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0)) + imx_writel(1, tzic_base + TZIC_DSMINT); + if (unlikely(imx_readl(tzic_base + TZIC_DSMINT) == 0)) return -EAGAIN; for (i = 0; i < 4; i++) - __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(i)), - tzic_base + TZIC_WAKEUP0(i)); + imx_writel(imx_readl(tzic_base + TZIC_ENSET0(i)), + tzic_base + TZIC_WAKEUP0(i)); return 0; } diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c index a1b07eeaaf5b..b821e34474b6 100644 --- a/arch/arm/mach-mediatek/platsmp.c +++ b/arch/arm/mach-mediatek/platsmp.c @@ -44,13 +44,21 @@ static const struct mtk_smp_boot_info mtk_mt6589_boot = { { 0x38, 0x3c, 0x40 }, }; +static const struct mtk_smp_boot_info mtk_mt7623_boot = { + 0x10202000, 0x34, + { 0x534c4131, 0x4c415332, 0x41534c33 }, + { 0x38, 0x3c, 0x40 }, +}; + static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot }, { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot }, + { .compatible = "mediatek,mt2701", .data = &mtk_mt8135_tz_boot }, }; static const struct of_device_id mtk_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, + { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot }, }; static void __iomem *mtk_smp_base; diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index 7b02ed218a42..f6ba589cd312 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -25,6 +25,7 @@ #include <linux/device.h> #include <linux/io.h> #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/omap-dma.h> #include <mach/tc.h> @@ -265,6 +266,42 @@ static const struct platform_device_info omap_dma_dev_info = { .num_res = 1, }; +/* OMAP730, OMAP850 */ +static const struct dma_slave_map omap7xx_sdma_map[] = { + { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(8) }, + { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(9) }, + { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(10) }, + { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(11) }, + { "mmci-omap.0", "tx", SDMA_FILTER_PARAM(21) }, + { "mmci-omap.0", "rx", SDMA_FILTER_PARAM(22) }, + { "omap_udc", "rx0", SDMA_FILTER_PARAM(26) }, + { "omap_udc", "rx1", SDMA_FILTER_PARAM(27) }, + { "omap_udc", "rx2", SDMA_FILTER_PARAM(28) }, + { "omap_udc", "tx0", SDMA_FILTER_PARAM(29) }, + { "omap_udc", "tx1", SDMA_FILTER_PARAM(30) }, + { "omap_udc", "tx2", SDMA_FILTER_PARAM(31) }, +}; + +/* OMAP1510, OMAP1610*/ +static const struct dma_slave_map omap1xxx_sdma_map[] = { + { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(8) }, + { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(9) }, + { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(10) }, + { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(11) }, + { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(16) }, + { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(17) }, + { "mmci-omap.0", "tx", SDMA_FILTER_PARAM(21) }, + { "mmci-omap.0", "rx", SDMA_FILTER_PARAM(22) }, + { "omap_udc", "rx0", SDMA_FILTER_PARAM(26) }, + { "omap_udc", "rx1", SDMA_FILTER_PARAM(27) }, + { "omap_udc", "rx2", SDMA_FILTER_PARAM(28) }, + { "omap_udc", "tx0", SDMA_FILTER_PARAM(29) }, + { "omap_udc", "tx1", SDMA_FILTER_PARAM(30) }, + { "omap_udc", "tx2", SDMA_FILTER_PARAM(31) }, + { "mmci-omap.1", "tx", SDMA_FILTER_PARAM(54) }, + { "mmci-omap.1", "rx", SDMA_FILTER_PARAM(55) }, +}; + static struct omap_system_dma_plat_info dma_plat_info __initdata = { .reg_map = reg_map, .channel_stride = 0x40, @@ -342,6 +379,14 @@ static int __init omap1_system_dma_init(void) p.dma_attr = d; p.errata = configure_dma_errata(); + if (cpu_is_omap7xx()) { + p.slave_map = omap7xx_sdma_map; + p.slavecnt = ARRAY_SIZE(omap7xx_sdma_map); + } else { + p.slave_map = omap1xxx_sdma_map; + p.slavecnt = ARRAY_SIZE(omap1xxx_sdma_map); + } + ret = platform_device_add_data(pdev, &p, sizeof(p)); if (ret) { dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 9cda974a3009..d7f1d69daf6d 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -18,7 +18,6 @@ #include <linux/slab.h> #include <linux/of.h> #include <linux/pinctrl/machine.h> -#include <linux/platform_data/mailbox-omap.h> #include <asm/mach-types.h> #include <asm/mach/map.h> @@ -66,32 +65,6 @@ static int __init omap3_l3_init(void) } omap_postcore_initcall(omap3_l3_init); -#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) -static inline void __init omap_init_mbox(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - struct omap_mbox_pdata *pdata; - - oh = omap_hwmod_lookup("mailbox"); - if (!oh) { - pr_err("%s: unable to find hwmod\n", __func__); - return; - } - if (!oh->dev_attr) { - pr_err("%s: hwmod doesn't have valid attrs\n", __func__); - return; - } - - pdata = (struct omap_mbox_pdata *)oh->dev_attr; - pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata)); - WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", - __func__, PTR_ERR(pdev)); -} -#else -static inline void omap_init_mbox(void) { } -#endif /* CONFIG_OMAP2PLUS_MBOX */ - static inline void omap_init_sti(void) {} #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) @@ -229,7 +202,6 @@ static int __init omap2_init_devices(void) * please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ - omap_init_mbox(); omap_init_mcspi(); omap_init_sham(); omap_init_aes(); diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 1ed4be184a29..e58c13a9bea5 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -28,6 +28,7 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/of.h> #include <linux/omap-dma.h> @@ -203,6 +204,108 @@ static unsigned configure_dma_errata(void) return errata; } +static const struct dma_slave_map omap24xx_sdma_map[] = { + { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, + { "omap-aes", "tx", SDMA_FILTER_PARAM(9) }, + { "omap-aes", "rx", SDMA_FILTER_PARAM(10) }, + { "omap-sham", "rx", SDMA_FILTER_PARAM(13) }, + { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, + { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, + { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, + { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, + { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, + { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, + { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, + { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, + { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, + { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, + { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, + { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, + { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, + { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, + { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, + { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, + { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, + { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, + { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, + { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, + { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, + { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, + { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, + { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, + { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, + { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, + { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, + { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, + { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, + { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, + { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, + { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, + { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, + { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, + { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, + { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, + { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, + { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, + { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, + { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, +}; + +static const struct dma_slave_map omap3xxx_sdma_map[] = { + { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, + { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, + { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, + { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, + { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, + { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, + { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, + { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, + { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, + { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, + { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, + { "omap_i2c.3", "tx", SDMA_FILTER_PARAM(25) }, + { "omap_i2c.3", "rx", SDMA_FILTER_PARAM(26) }, + { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, + { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, + { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, + { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, + { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, + { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, + { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, + { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, + { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, + { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, + { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, + { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, + { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, + { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, + { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, + { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, + { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, + { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, + { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, + { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, + { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, + { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, + { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, + { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, + { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, + { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, + { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, + { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, + { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, + { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, + { "omap-aes", "tx", SDMA_FILTER_PARAM(65) }, + { "omap-aes", "rx", SDMA_FILTER_PARAM(66) }, + { "omap-sham", "rx", SDMA_FILTER_PARAM(69) }, + { "omap2_mcspi.3", "tx0", SDMA_FILTER_PARAM(70) }, + { "omap2_mcspi.3", "rx0", SDMA_FILTER_PARAM(71) }, + { "omap_hsmmc.2", "tx", SDMA_FILTER_PARAM(77) }, + { "omap_hsmmc.2", "rx", SDMA_FILTER_PARAM(78) }, + { "omap_uart.3", "tx", SDMA_FILTER_PARAM(81) }, + { "omap_uart.3", "rx", SDMA_FILTER_PARAM(82) }, +}; + static struct omap_system_dma_plat_info dma_plat_info __initdata = { .reg_map = reg_map, .channel_stride = 0x60, @@ -231,6 +334,20 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; p.errata = configure_dma_errata(); + if (!of_have_populated_dt()) { + if (soc_is_omap24xx()) { + p.slave_map = omap24xx_sdma_map; + p.slavecnt = ARRAY_SIZE(omap24xx_sdma_map); + } else if (soc_is_omap34xx() || soc_is_omap3630()) { + p.slave_map = omap3xxx_sdma_map; + p.slavecnt = ARRAY_SIZE(omap3xxx_sdma_map); + } else { + pr_err("%s: The legacy DMA map is not provided!\n", + __func__); + return -ENODEV; + } + } + pdev = omap_device_build(name, 0, oh, &p, sizeof(p)); if (IS_ERR(pdev)) { pr_err("%s: Can't build omap_device for %s:%s.\n", diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 0a985325cd64..9869a75c5d96 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3583,14 +3583,14 @@ static struct omap_hwmod_class_sysconfig omap34xx_ssi_sysc = { .sysc_fields = &omap_hwmod_sysc_type1, }; -static struct omap_hwmod_class omap34xx_ssi_hwmod_class = { +static struct omap_hwmod_class omap3xxx_ssi_hwmod_class = { .name = "ssi", .sysc = &omap34xx_ssi_sysc, }; -static struct omap_hwmod omap34xx_ssi_hwmod = { +static struct omap_hwmod omap3xxx_ssi_hwmod = { .name = "ssi", - .class = &omap34xx_ssi_hwmod_class, + .class = &omap3xxx_ssi_hwmod_class, .clkdm_name = "core_l4_clkdm", .main_clk = "ssi_ssr_fck", .prcm = { @@ -3605,9 +3605,9 @@ static struct omap_hwmod omap34xx_ssi_hwmod = { }; /* L4 CORE -> SSI */ -static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = { +static struct omap_hwmod_ocp_if omap3xxx_l4_core__ssi = { .master = &omap3xxx_l4_core_hwmod, - .slave = &omap34xx_ssi_hwmod, + .slave = &omap3xxx_ssi_hwmod, .clk = "ssi_ick", .user = OCP_USER_MPU | OCP_USER_SDMA, }; @@ -3760,7 +3760,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_sad2d__l3, &omap3xxx_l4_core__mmu_isp, &omap3xxx_l3_main__mmu_iva, - &omap34xx_l4_core__ssi, + &omap3xxx_l4_core__ssi, NULL }; @@ -3784,6 +3784,7 @@ static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_sad2d__l3, &omap3xxx_l4_core__mmu_isp, &omap3xxx_l3_main__mmu_iva, + &omap3xxx_l4_core__ssi, NULL }; diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index e97a894b5f88..97fd399202dc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -1020,9 +1020,21 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { NULL, }; +static struct omap_hwmod_ocp_if *am43xx_rtc_hwmod_ocp_ifs[] __initdata = { + &am33xx_l4_wkup__rtc, + NULL, +}; + int __init am43xx_hwmod_init(void) { + int ret; + omap_hwmod_am43xx_reg(); omap_hwmod_init(); - return omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); + ret = omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); + + if (!ret && of_machine_is_compatible("ti,am4372")) + ret = omap_hwmod_register_links(am43xx_rtc_hwmod_ocp_ifs); + + return ret; } diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 848356e38b74..9442d89bd229 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -430,6 +430,67 @@ static struct omap_hwmod dra7xx_dma_system_hwmod = { }; /* + * 'tpcc' class + * + */ +static struct omap_hwmod_class dra7xx_tpcc_hwmod_class = { + .name = "tpcc", +}; + +static struct omap_hwmod dra7xx_tpcc_hwmod = { + .name = "tpcc", + .class = &dra7xx_tpcc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPCC_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPCC_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'tptc' class + * + */ +static struct omap_hwmod_class dra7xx_tptc_hwmod_class = { + .name = "tptc", +}; + +/* tptc0 */ +static struct omap_hwmod dra7xx_tptc0_hwmod = { + .name = "tptc0", + .class = &dra7xx_tptc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPTC1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPTC1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* tptc1 */ +static struct omap_hwmod dra7xx_tptc1_hwmod = { + .name = "tptc1", + .class = &dra7xx_tptc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPTC2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPTC2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* * 'dss' class * */ @@ -1482,8 +1543,7 @@ static struct omap_hwmod_class_sysconfig dra7xx_ocp2scp_sysc = { .syss_offs = 0x0014, .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -1527,19 +1587,49 @@ static struct omap_hwmod dra7xx_ocp2scp3_hwmod = { * */ +/* + * As noted in documentation for _reset() in omap_hwmod.c, the stock reset + * functionality of OMAP HWMOD layer does not deassert the hardreset lines + * associated with an IP automatically leaving the driver to handle that + * by itself. This does not work for PCIeSS which needs the reset lines + * deasserted for the driver to start accessing registers. + * + * We use a PCIeSS HWMOD class specific reset handler to deassert the hardreset + * lines after asserting them. + */ +static int dra7xx_pciess_reset(struct omap_hwmod *oh) +{ + int i; + + for (i = 0; i < oh->rst_lines_cnt; i++) { + omap_hwmod_assert_hardreset(oh, oh->rst_lines[i].name); + omap_hwmod_deassert_hardreset(oh, oh->rst_lines[i].name); + } + + return 0; +} + static struct omap_hwmod_class dra7xx_pciess_hwmod_class = { .name = "pcie", + .reset = dra7xx_pciess_reset, }; /* pcie1 */ +static struct omap_hwmod_rst_info dra7xx_pciess1_resets[] = { + { .name = "pcie", .rst_shift = 0 }, +}; + static struct omap_hwmod dra7xx_pciess1_hwmod = { .name = "pcie1", .class = &dra7xx_pciess_hwmod_class, .clkdm_name = "pcie_clkdm", + .rst_lines = dra7xx_pciess1_resets, + .rst_lines_cnt = ARRAY_SIZE(dra7xx_pciess1_resets), .main_clk = "l4_root_clk_div", .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET, + .rstctrl_offs = DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_L3INIT_PCIESS1_CONTEXT_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, @@ -1547,14 +1637,22 @@ static struct omap_hwmod dra7xx_pciess1_hwmod = { }; /* pcie2 */ +static struct omap_hwmod_rst_info dra7xx_pciess2_resets[] = { + { .name = "pcie", .rst_shift = 1 }, +}; + +/* pcie2 */ static struct omap_hwmod dra7xx_pciess2_hwmod = { .name = "pcie2", .class = &dra7xx_pciess_hwmod_class, .clkdm_name = "pcie_clkdm", + .rst_lines = dra7xx_pciess2_resets, + .rst_lines_cnt = ARRAY_SIZE(dra7xx_pciess2_resets), .main_clk = "l4_root_clk_div", .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS2_CLKCTRL_OFFSET, + .rstctrl_offs = DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_L3INIT_PCIESS2_CONTEXT_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, @@ -2549,6 +2647,30 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__dma_system = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l3_main_1 -> tpcc */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tpcc = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tpcc_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_1 -> tptc0 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc0 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tptc0_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_1 -> tptc1 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc1 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tptc1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + static struct omap_hwmod_addr_space dra7xx_dss_addrs[] = { { .name = "family", @@ -3366,6 +3488,9 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { &dra7xx_l3_main_1__mcasp3, &dra7xx_gmac__mdio, &dra7xx_l4_cfg__dma_system, + &dra7xx_l3_main_1__tpcc, + &dra7xx_l3_main_1__tptc0, + &dra7xx_l3_main_1__tptc1, &dra7xx_l3_main_1__dss, &dra7xx_l3_main_1__dispc, &dra7xx_l3_main_1__hdmi, diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index e493ae372910..609e2397ea47 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -228,6 +228,42 @@ static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_med = { .user = OCP_USER_MPU, }; +/* RTC */ +static struct omap_hwmod_class_sysconfig ti81xx_rtc_sysc = { + .rev_offs = 0x74, + .sysc_offs = 0x78, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = SIDLE_FORCE | SIDLE_NO | + SIDLE_SMART | SIDLE_SMART_WKUP, + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class ti81xx_rtc_hwmod_class = { + .name = "rtc", + .sysc = &ti81xx_rtc_sysc, +}; + +struct omap_hwmod ti81xx_rtc_hwmod = { + .name = "rtc", + .class = &ti81xx_rtc_hwmod_class, + .clkdm_name = "alwon_l3s_clkdm", + .flags = HWMOD_NO_IDLEST, + .main_clk = "sysclk18_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DM81XX_CM_ALWON_RTC_CLKCTRL, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if ti81xx_l4_ls__rtc = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &ti81xx_rtc_hwmod, + .clk = "sysclk6_ck", + .user = OCP_USER_MPU, +}; + /* UART common */ static struct omap_hwmod_class_sysconfig uart_sysc = { .rev_offs = 0x50, @@ -1376,6 +1412,7 @@ static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = { &dm81xx_l4_ls__mcspi1, &dm814x_l4_ls__mmc1, &dm814x_l4_ls__mmc2, + &ti81xx_l4_ls__rtc, &dm81xx_alwon_l3_fast__tpcc, &dm81xx_alwon_l3_fast__tptc0, &dm81xx_alwon_l3_fast__tptc1, @@ -1415,6 +1452,7 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { &dm81xx_l4_ls__gpio1, &dm81xx_l4_ls__gpio2, &dm81xx_l4_ls__elm, + &ti81xx_l4_ls__rtc, &dm816x_l4_ls__mmc1, &dm816x_l4_ls__timer1, &dm816x_l4_ls__timer2, diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index e781e4fae13a..a935d28443da 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -23,6 +23,8 @@ #include <linux/platform_data/pinctrl-single.h> #include <linux/platform_data/iommu-omap.h> #include <linux/platform_data/wkup_m3.h> +#include <linux/platform_data/pwm_omap_dmtimer.h> +#include <plat/dmtimer.h> #include "common.h" #include "common-board-devices.h" @@ -449,6 +451,24 @@ void omap_auxdata_legacy_init(struct device *dev) dev->platform_data = &twl_gpio_auxdata; } +/* Dual mode timer PWM callbacks platdata */ +#if IS_ENABLED(CONFIG_OMAP_DM_TIMER) +struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = { + .request_by_node = omap_dm_timer_request_by_node, + .free = omap_dm_timer_free, + .enable = omap_dm_timer_enable, + .disable = omap_dm_timer_disable, + .get_fclk = omap_dm_timer_get_fclk, + .start = omap_dm_timer_start, + .stop = omap_dm_timer_stop, + .set_load = omap_dm_timer_set_load, + .set_match = omap_dm_timer_set_match, + .set_pwm = omap_dm_timer_set_pwm, + .set_prescaler = omap_dm_timer_set_prescaler, + .write_counter = omap_dm_timer_write_counter, +}; +#endif + /* * Few boards still need auxdata populated before we populate * the dev entries in of_platform_populate(). @@ -502,6 +522,9 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d00000, "44d00000.wkup_m3", &wkup_m3_data), #endif +#if IS_ENABLED(CONFIG_OMAP_DM_TIMER) + OF_DEV_AUXDATA("ti,omap-dmtimer-pwm", 0, NULL, &pwm_dmtimer_pdata), +#endif #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu", &omap4_iommu_pdata), diff --git a/arch/arm/mach-omap2/prm7xx.h b/arch/arm/mach-omap2/prm7xx.h index cc1e6a2b97f6..294deed956f3 100644 --- a/arch/arm/mach-omap2/prm7xx.h +++ b/arch/arm/mach-omap2/prm7xx.h @@ -360,6 +360,7 @@ /* PRM.L3INIT_PRM register offsets */ #define DRA7XX_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000 #define DRA7XX_PM_L3INIT_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET 0x0010 #define DRA7XX_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028 #define DRA7XX_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c #define DRA7XX_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030 diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index eafd120b53f1..1b9f0520dea9 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -86,13 +86,18 @@ ENTRY(enable_omap3630_toggle_l2_on_restore) stmfd sp!, {lr} @ save registers on stack /* Setup so that we will disable and enable l2 */ mov r1, #0x1 - adrl r2, l2dis_3630 @ may be too distant for plain adr - str r1, [r2] + adrl r3, l2dis_3630_offset @ may be too distant for plain adr + ldr r2, [r3] @ value for offset + str r1, [r2, r3] @ write to l2dis_3630 ldmfd sp!, {pc} @ restore regs and return ENDPROC(enable_omap3630_toggle_l2_on_restore) - .text -/* Function to call rom code to save secure ram context */ +/* + * Function to call rom code to save secure ram context. This gets + * relocated to SRAM, so it can be all in .data section. Otherwise + * we need to initialize api_params separately. + */ + .data .align 3 ENTRY(save_secure_ram_context) stmfd sp!, {r4 - r11, lr} @ save registers on stack @@ -126,6 +131,8 @@ ENDPROC(save_secure_ram_context) ENTRY(save_secure_ram_context_sz) .word . - save_secure_ram_context + .text + /* * ====================== * == Idle entry point == @@ -289,12 +296,6 @@ wait_sdrc_ready: bic r5, r5, #0x40 str r5, [r4] -/* - * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a - * base instead. - * Be careful not to clobber r7 when maintaing this code. - */ - is_dll_in_lock_mode: /* Is dll in lock mode? */ ldr r4, sdrc_dlla_ctrl @@ -302,11 +303,7 @@ is_dll_in_lock_mode: tst r5, #0x4 bne exit_nonoff_modes @ Return if locked /* wait till dll locks */ - adr r7, kick_counter wait_dll_lock_timed: - ldr r4, wait_dll_lock_counter - add r4, r4, #1 - str r4, [r7, #wait_dll_lock_counter - kick_counter] ldr r4, sdrc_dlla_status /* Wait 20uS for lock */ mov r6, #8 @@ -330,9 +327,6 @@ kick_dll: orr r6, r6, #(1<<3) @ enable dll str r6, [r4] dsb - ldr r4, kick_counter - add r4, r4, #1 - str r4, [r7] @ kick_counter b wait_dll_lock_timed exit_nonoff_modes: @@ -360,15 +354,6 @@ sdrc_dlla_status: .word SDRC_DLLA_STATUS_V sdrc_dlla_ctrl: .word SDRC_DLLA_CTRL_V - /* - * When exporting to userspace while the counters are in SRAM, - * these 2 words need to be at the end to facilitate retrival! - */ -kick_counter: - .word 0 -wait_dll_lock_counter: - .word 0 - ENTRY(omap3_do_wfi_sz) .word . - omap3_do_wfi @@ -437,7 +422,9 @@ ENTRY(omap3_restore) cmp r2, #0x0 @ Check if target power state was OFF or RET bne logic_l1_restore - ldr r0, l2dis_3630 + adr r1, l2dis_3630_offset @ address for offset + ldr r0, [r1] @ value for offset + ldr r0, [r1, r0] @ value at l2dis_3630 cmp r0, #0x1 @ should we disable L2 on 3630? bne skipl2dis mrc p15, 0, r0, c1, c0, 1 @@ -449,12 +436,14 @@ skipl2dis: and r1, #0x700 cmp r1, #0x300 beq l2_inv_gp + adr r0, l2_inv_api_params_offset + ldr r3, [r0] + add r3, r3, r0 @ r3 points to dummy parameters mov r0, #40 @ set service ID for PPA mov r12, r0 @ copy secure Service ID in r12 mov r1, #0 @ set task id for ROM code in r1 mov r2, #4 @ set some flags in r2, r6 mov r6, #0xff - adr r3, l2_inv_api_params @ r3 points to dummy parameters dsb @ data write barrier dmb @ data memory barrier smc #1 @ call SMI monitor (smi #1) @@ -488,8 +477,8 @@ skipl2dis: b logic_l1_restore .align -l2_inv_api_params: - .word 0x1, 0x00 +l2_inv_api_params_offset: + .long l2_inv_api_params - . l2_inv_gp: /* Execute smi to invalidate L2 cache */ mov r12, #0x1 @ set up to invalidate L2 @@ -506,7 +495,9 @@ l2_inv_gp: mov r12, #0x2 smc #0 @ Call SMI monitor (smieq) logic_l1_restore: - ldr r1, l2dis_3630 + adr r0, l2dis_3630_offset @ adress for offset + ldr r1, [r0] @ value for offset + ldr r1, [r0, r1] @ value at l2dis_3630 cmp r1, #0x1 @ Test if L2 re-enable needed on 3630 bne skipl2reen mrc p15, 0, r1, c1, c0, 1 @@ -535,9 +526,17 @@ control_stat: .word CONTROL_STAT control_mem_rta: .word CONTROL_MEM_RTA_CTRL +l2dis_3630_offset: + .long l2dis_3630 - . + + .data l2dis_3630: .word 0 + .data +l2_inv_api_params: + .word 0x1, 0x00 + /* * Internal functions */ diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index 9b09d85d811a..c7a3b4aab4b5 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -29,12 +29,6 @@ dsb .endm -ppa_zero_params: - .word 0x0 - -ppa_por_params: - .word 1, 0 - #ifdef CONFIG_ARCH_OMAP4 /* @@ -266,7 +260,9 @@ ENTRY(omap4_cpu_resume) beq skip_ns_smp_enable ppa_actrl_retry: mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX - adr r3, ppa_zero_params @ Pointer to parameters + adr r1, ppa_zero_params_offset + ldr r3, [r1] + add r3, r3, r1 @ Pointer to ppa_zero_params mov r1, #0x0 @ Process ID mov r2, #0x4 @ Flag mov r6, #0xff @@ -303,7 +299,9 @@ skip_ns_smp_enable: ldr r0, =OMAP4_PPA_L2_POR_INDEX ldr r1, =OMAP44XX_SAR_RAM_BASE ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET] - adr r3, ppa_por_params + adr r1, ppa_por_params_offset + ldr r3, [r1] + add r3, r3, r1 @ Pointer to ppa_por_params str r4, [r3, #0x04] mov r1, #0x0 @ Process ID mov r2, #0x4 @ Flag @@ -328,6 +326,8 @@ skip_l2en: #endif b cpu_resume @ Jump to generic resume +ppa_por_params_offset: + .long ppa_por_params - . ENDPROC(omap4_cpu_resume) #endif /* CONFIG_ARCH_OMAP4 */ @@ -380,4 +380,13 @@ ENTRY(omap_do_wfi) nop ldmfd sp!, {pc} +ppa_zero_params_offset: + .long ppa_zero_params - . ENDPROC(omap_do_wfi) + + .data +ppa_zero_params: + .word 0 + +ppa_por_params: + .word 1, 0 diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 79ca3c3eb2af..70df8f6cddcc 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -181,6 +181,14 @@ static inline int is_ti ##class (void) \ return (GET_TI_CLASS == (id)) ? 1 : 0; \ } +#define GET_DRA_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_DRA_CLASS(class, id) \ +static inline int is_dra ##class (void) \ +{ \ + return (GET_DRA_CLASS == (id)) ? 1 : 0; \ +} + #define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) #define IS_OMAP_SUBCLASS(subclass, id) \ @@ -201,6 +209,12 @@ static inline int is_am ##subclass (void) \ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ } +#define IS_DRA_SUBCLASS(subclass, id) \ +static inline int is_dra ##subclass (void) \ +{ \ + return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ +} + IS_OMAP_CLASS(24xx, 0x24) IS_OMAP_CLASS(34xx, 0x34) IS_OMAP_CLASS(44xx, 0x44) @@ -210,6 +224,7 @@ IS_AM_CLASS(33xx, 0x33) IS_AM_CLASS(43xx, 0x43) IS_TI_CLASS(81xx, 0x81) +IS_DRA_CLASS(7xx, 0x7) IS_OMAP_SUBCLASS(242x, 0x242) IS_OMAP_SUBCLASS(243x, 0x243) @@ -224,6 +239,8 @@ IS_TI_SUBCLASS(816x, 0x816) IS_TI_SUBCLASS(814x, 0x814) IS_AM_SUBCLASS(335x, 0x335) IS_AM_SUBCLASS(437x, 0x437) +IS_DRA_SUBCLASS(75x, 0x75) +IS_DRA_SUBCLASS(72x, 0x72) #define soc_is_omap24xx() 0 #define soc_is_omap242x() 0 @@ -397,9 +414,9 @@ IS_OMAP_TYPE(3430, 0x3430) #undef soc_is_dra7xx #undef soc_is_dra74x #undef soc_is_dra72x -#define soc_is_dra7xx() (of_machine_is_compatible("ti,dra7")) -#define soc_is_dra74x() (of_machine_is_compatible("ti,dra74")) -#define soc_is_dra72x() (of_machine_is_compatible("ti,dra72")) +#define soc_is_dra7xx() is_dra7xx() +#define soc_is_dra74x() is_dra75x() +#define soc_is_dra72x() is_dra72x() #endif /* Various silicon revisions for omap2 */ diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index f09683687963..7ee4652b4c61 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -297,7 +297,6 @@ config MACH_MAGICIAN config MACH_MIOA701 bool "Mitac Mio A701 Support" - select GPIO_SYSFS select IWMMXT select PXA27x help @@ -529,7 +528,7 @@ config MACH_TOSA config TOSA_BT tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" - depends on MACH_TOSA + depends on MACH_TOSA && NET select RFKILL help This is a simple driver that is able to control diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 37d8d85662f0..913a319c7b00 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -1203,6 +1203,7 @@ void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info) static struct mmp_dma_platdata pxa_dma_pdata = { .dma_channels = 0, + .nb_requestors = 0, }; static struct resource pxa_dma_resource[] = { @@ -1231,7 +1232,7 @@ static struct platform_device pxa2xx_pxa_dma = { .resource = pxa_dma_resource, }; -void __init pxa2xx_set_dmac_info(int nb_channels) +void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors) { pxa_dma_pdata.dma_channels = nb_channels; pxa_register_device(&pxa2xx_pxa_dma, &pxa_dma_pdata); diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index 0b00b226f54b..e838b11fb8c7 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -57,7 +57,7 @@ struct gpio_vbus_mach_info e7xx_udc_info = { .gpio_pullup_inverted = 1 }; -static struct platform_device e7xx_gpio_vbus = { +static struct platform_device e7xx_gpio_vbus __maybe_unused = { .name = "gpio-vbus", .id = -1, .dev = { @@ -126,7 +126,7 @@ struct resource eseries_tmio_resources[] = { }; /* Some e-series hardware cannot control the 32K clock */ -static void __init eseries_register_clks(void) +static void __init __maybe_unused eseries_register_clks(void) { clk_register_fixed_rate(NULL, "CLK_CK32K", NULL, CLK_IS_ROOT, 32768); } diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index 6815a9357774..9c5b2fb054f9 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -139,14 +139,14 @@ static void gumstix_setup_bt_clock(void) { int timeout = 500; - if (!(OSCC & OSCC_OOK)) + if (!(readl(OSCC) & OSCC_OOK)) pr_warn("32kHz clock was not on. Bootloader may need to be updated\n"); else return; - OSCC |= OSCC_OON; + writel(readl(OSCC) | OSCC_OON, OSCC); do { - if (OSCC & OSCC_OOK) + if (readl(OSCC) & OSCC_OOK) break; udelay(1); } while (--timeout); diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h index f1dd62946b36..5537d5601d70 100644 --- a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h @@ -134,10 +134,10 @@ /* * PXA2xx specific Core clock definitions */ -#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ -#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ -#define CKEN __REG(0x41300004) /* Clock Enable Register */ -#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ +#define CCCR io_p2v(0x41300000) /* Core Clock Configuration Register */ +#define CCSR io_p2v(0x4130000C) /* Core Clock Status Register */ +#define CKEN io_p2v(0x41300004) /* Clock Enable Register */ +#define OSCC io_p2v(0x41300008) /* Oscillator Configuration Register */ #define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ #define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h index f4d48d20754e..888bf7ade15a 100644 --- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h @@ -18,7 +18,7 @@ /* * Oscillator Configuration Register (OSCC) */ -#define OSCC __REG(0x41350000) /* Oscillator Configuration Register */ +#define OSCC io_p2v(0x41350000) /* Oscillator Configuration Register */ #define OSCC_PEN (1 << 11) /* 13MHz POUT */ diff --git a/arch/arm/mach-pxa/pm.h b/arch/arm/mach-pxa/pm.h index 51558bcee999..3aab90d8d2b7 100644 --- a/arch/arm/mach-pxa/pm.h +++ b/arch/arm/mach-pxa/pm.h @@ -29,6 +29,9 @@ extern int pxa_pm_enter(suspend_state_t state); extern int pxa_pm_prepare(void); extern void pxa_pm_finish(void); +extern const char pm_enter_standby_start[], pm_enter_standby_end[]; +extern int pxa3xx_finish_suspend(unsigned long); + /* NOTE: this is for PM debugging on Lubbock, it's really a big * ugly, but let's keep the crap minimum here, instead of direct * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c diff --git a/arch/arm/mach-pxa/pxa-dt.c b/arch/arm/mach-pxa/pxa-dt.c index 8e0e62ccdced..f128133a8f30 100644 --- a/arch/arm/mach-pxa/pxa-dt.c +++ b/arch/arm/mach-pxa/pxa-dt.c @@ -19,42 +19,18 @@ #include "generic.h" #ifdef CONFIG_PXA3xx -static const struct of_dev_auxdata const pxa3xx_auxdata_lookup[] __initconst = { - OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL), - OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL), - OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL), - OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL), - OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL), - OF_DEV_AUXDATA("intel,pxa3xx-gpio", 0x40e00000, "pxa3xx-gpio", NULL), - OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL), - OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL), - OF_DEV_AUXDATA("mrvl,pwri2c", 0x40f500c0, "pxa3xx-i2c.1", NULL), - OF_DEV_AUXDATA("marvell,pxa3xx-nand", 0x43100000, "pxa3xx-nand", NULL), - {} -}; - -static void __init pxa3xx_dt_init(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, - pxa3xx_auxdata_lookup, NULL); -} - static const char *const pxa3xx_dt_board_compat[] __initconst = { "marvell,pxa300", "marvell,pxa310", "marvell,pxa320", NULL, }; -#endif -#ifdef CONFIG_PXA3xx DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)") .map_io = pxa3xx_map_io, .init_irq = pxa3xx_dt_init_irq, .handle_irq = pxa3xx_handle_irq, - .init_time = pxa_timer_init, .restart = pxa_restart, - .init_machine = pxa3xx_dt_init, .dt_compat = pxa3xx_dt_board_compat, MACHINE_END #endif diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index a177bf45feef..823504f48f80 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -206,7 +206,7 @@ static int __init pxa25x_init(void) register_syscore_ops(&pxa_irq_syscore_ops); register_syscore_ops(&pxa2xx_mfp_syscore_ops); - pxa2xx_set_dmac_info(16); + pxa2xx_set_dmac_info(16, 40); pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info); ret = platform_add_devices(pxa25x_devices, ARRAY_SIZE(pxa25x_devices)); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 8dfd1755c659..2eaa341dd3f8 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -132,7 +132,8 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) #ifndef CONFIG_IWMMXT u64 acc0; - asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mra %Q0, %R0, acc0" : "=r" (acc0)); #endif /* ensure voltage-change sequencer not initiated, which hangs */ @@ -151,7 +152,8 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: cpu_suspend(pwrmode, pxa27x_finish_suspend); #ifndef CONFIG_IWMMXT - asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mar acc0, %Q0, %R0" : "=r" (acc0)); #endif break; } @@ -309,7 +311,7 @@ static int __init pxa27x_init(void) if (!of_have_populated_dt()) { pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info); - pxa2xx_set_dmac_info(32); + pxa2xx_set_dmac_info(32, 75); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index a1c4c888f246..3c9184d1d6b9 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -68,7 +68,6 @@ static unsigned long wakeup_src; */ static void pxa3xx_cpu_standby(unsigned int pwrmode) { - extern const char pm_enter_standby_start[], pm_enter_standby_end[]; void (*fn)(unsigned int) = (void __force *)(sram + 0x8000); memcpy_toio(sram + 0x8000, pm_enter_standby_start, @@ -103,11 +102,10 @@ static void pxa3xx_cpu_pm_suspend(void) #ifndef CONFIG_IWMMXT u64 acc0; - asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mra %Q0, %R0, acc0" : "=r" (acc0)); #endif - extern int pxa3xx_finish_suspend(unsigned long); - /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); CKENB |= 1 << (CKEN_HSIO2 & 0x1f); @@ -133,7 +131,8 @@ static void pxa3xx_cpu_pm_suspend(void) AD3ER = 0; #ifndef CONFIG_IWMMXT - asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mar acc0, %Q0, %R0" : "=r" (acc0)); #endif } @@ -450,7 +449,7 @@ static int __init pxa3xx_init(void) if (of_have_populated_dt()) return 0; - pxa2xx_set_dmac_info(32); + pxa2xx_set_dmac_info(32, 100); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) return ret; diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 825f903ab77e..d9578bc49fdc 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -201,7 +201,7 @@ static void __init spitz_scoop_init(void) } /* Power control is shared with between one of the CF slots and SD */ -static void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) +static void __maybe_unused spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) { unsigned short cpr; unsigned long flags; diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 515b7ddda8aa..3b94ecfb9426 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -910,7 +910,7 @@ static void __init zeus_map_io(void) PMCR = PSPR = 0; /* enable internal 32.768Khz oscillator (ignore OSCC_OOK) */ - OSCC |= OSCC_OON; + writel(readl(OSCC) | OSCC_OON, OSCC); /* Some clock cycles later (from OSCC_ON), programme PCFR (OPDE...). * float chip selects and PCMCIA */ diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index def40a0dd60c..70ab4a25a5f8 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig @@ -1,5 +1,6 @@ menuconfig ARCH_REALVIEW - bool "ARM Ltd. RealView family" if ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7 + bool "ARM Ltd. RealView family" + depends on ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7 select ARM_AMBA select ARM_TIMER_SP804 select COMMON_CLK_VERSATILE diff --git a/arch/arm/mach-realview/platsmp-dt.c b/arch/arm/mach-realview/platsmp-dt.c index 65585392655b..6964e8876061 100644 --- a/arch/arm/mach-realview/platsmp-dt.c +++ b/arch/arm/mach-realview/platsmp-dt.c @@ -80,7 +80,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus) virt_to_phys(versatile_secondary_startup)); } -struct smp_operations realview_dt_smp_ops __initdata = { +static const struct smp_operations realview_dt_smp_ops __initconst = { .smp_prepare_cpus = realview_smp_prepare_cpus, .smp_secondary_init = versatile_secondary_init, .smp_boot_secondary = versatile_boot_secondary, diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index cd5f171f83ce..2824b81f1a39 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -6,28 +6,30 @@ config ARCH_SHMOBILE_MULTI config PM_RCAR bool - select PM_GENERIC_DOMAINS if PM + select PM + select PM_GENERIC_DOMAINS config PM_RMOBILE bool + select PM select PM_GENERIC_DOMAINS config ARCH_RCAR_GEN1 bool - select PM_RCAR if PM || SMP + select PM_RCAR select RENESAS_INTC_IRQPIN select SYS_SUPPORTS_SH_TMU config ARCH_RCAR_GEN2 bool - select PM_RCAR if PM || SMP + select PM_RCAR select RENESAS_IRQC select SYS_SUPPORTS_SH_CMT select PCI_DOMAINS if PCI config ARCH_RMOBILE bool - select PM_RMOBILE if PM + select PM_RMOBILE select SYS_SUPPORTS_SH_CMT select SYS_SUPPORTS_SH_TMU @@ -55,7 +57,8 @@ config ARCH_EMEV2 config ARCH_R7S72100 bool "RZ/A1H (R7S72100)" - select PM_GENERIC_DOMAINS if PM + select PM + select PM_GENERIC_DOMAINS select SYS_SUPPORTS_SH_MTU2 config ARCH_R8A73A4 diff --git a/arch/arm/mach-shmobile/emev2.h b/arch/arm/mach-shmobile/emev2.h new file mode 100644 index 000000000000..916d25f6780e --- /dev/null +++ b/arch/arm/mach-shmobile/emev2.h @@ -0,0 +1,6 @@ +#ifndef __ASM_EMEV2_H__ +#define __ASM_EMEV2_H__ + +extern const struct smp_operations emev2_smp_ops; + +#endif /* __ASM_EMEV2_H__ */ diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 10b7cb5dcb3a..3c99aaf65325 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -18,35 +18,17 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include "common.h" - -static struct map_desc emev2_io_desc[] __initdata = { -#ifdef CONFIG_SMP - /* 2M mapping for SCU + L2 controller */ - { - .virtual = 0xf0000000, - .pfn = __phys_to_pfn(0x1e000000), - .length = SZ_2M, - .type = MT_DEVICE - }, -#endif -}; -static void __init emev2_map_io(void) -{ - iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc)); -} +#include "common.h" +#include "emev2.h" static const char *const emev2_boards_compat_dt[] __initconst = { "renesas,emev2", NULL, }; -extern const struct smp_operations emev2_smp_ops; - DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") .smp = smp_ops(emev2_smp_ops), - .map_io = emev2_map_io, .init_early = shmobile_init_delay, .init_late = shmobile_init_late, .dt_compat = emev2_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 0c8f80c5b04d..db6dbfbaf9f1 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -23,41 +23,9 @@ #include <asm/mach/map.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> -#include <asm/hardware/cache-l2x0.h> #include "common.h" -static struct map_desc r8a7740_io_desc[] __initdata = { - /* - * for CPGA/INTC/PFC - * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 160 << 20, - .type = MT_DEVICE_NONSHARED - }, -#ifdef CONFIG_CACHE_L2X0 - /* - * for l2x0_init() - * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000 - */ - { - .virtual = 0xf0002000, - .pfn = __phys_to_pfn(0xf0100000), - .length = PAGE_SIZE, - .type = MT_DEVICE_NONSHARED - }, -#endif -}; - -static void __init r8a7740_map_io(void) -{ - debug_ll_io_init(); - iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc)); -} - /* * r8a7740 chip has lasting errata on MERAM buffer. * this is work-around for it. @@ -110,10 +78,6 @@ static void __init r8a7740_generic_init(void) { r8a7740_meram_workaround(); -#ifdef CONFIG_CACHE_L2X0 - /* Shared attribute override enable, 32K*8way */ - l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff); -#endif of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -123,7 +87,8 @@ static const char *const r8a7740_boards_compat_dt[] __initconst = { }; DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)") - .map_io = r8a7740_map_io, + .l2c_aux_val = 0, + .l2c_aux_mask = ~0, .init_early = shmobile_init_delay, .init_irq = r8a7740_init_irq_of, .init_machine = r8a7740_generic_init, diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index adbac6963f2b..871220bf5870 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -21,7 +21,9 @@ #include <linux/delay.h> #include <asm/smp_plat.h> #include <asm/smp_scu.h> + #include "common.h" +#include "emev2.h" #define EMEV2_SCU_BASE 0x1e000000 #define EMEV2_SMU_BASE 0xe0110000 diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c index f2ad7723d034..ceee47735eec 100644 --- a/arch/arm/mach-stm32/board-dt.c +++ b/arch/arm/mach-stm32/board-dt.c @@ -10,6 +10,7 @@ static const char *const stm32_compat[] __initconst = { "st,stm32f429", + "st,stm32f469", NULL }; diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index c2be98f38e73..3c156190a1d4 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c @@ -69,6 +69,7 @@ MACHINE_END static const char * const sun8i_board_dt_compat[] = { "allwinner,sun8i-a23", "allwinner,sun8i-a33", + "allwinner,sun8i-a83t", "allwinner,sun8i-h3", NULL, }; diff --git a/arch/arm/mach-tango/Kconfig b/arch/arm/mach-tango/Kconfig index d6a3714b096e..ebe15b93bbe8 100644 --- a/arch/arm/mach-tango/Kconfig +++ b/arch/arm/mach-tango/Kconfig @@ -1,5 +1,6 @@ config ARCH_TANGO - bool "Sigma Designs Tango4 (SMP87xx)" if ARCH_MULTI_V7 + bool "Sigma Designs Tango4 (SMP87xx)" + depends on ARCH_MULTI_V7 # Cortex-A9 MPCore r3p0, PL310 r3p2 select ARCH_HAS_HOLES_MEMORYMODEL select ARM_ERRATA_754322 diff --git a/arch/arm/mach-tango/platsmp.c b/arch/arm/mach-tango/platsmp.c index a18d5a34e2f5..a21f55e000d2 100644 --- a/arch/arm/mach-tango/platsmp.c +++ b/arch/arm/mach-tango/platsmp.c @@ -9,7 +9,7 @@ static int tango_boot_secondary(unsigned int cpu, struct task_struct *idle) return 0; } -static struct smp_operations tango_smp_ops __initdata = { +static const struct smp_operations tango_smp_ops __initconst = { .smp_boot_secondary = tango_boot_secondary, }; diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 6f39d03cc27e..860ffb663f02 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -150,8 +150,6 @@ out: static void __init zynq_timer_init(void) { - zynq_early_slcr_init(); - zynq_clock_init(); of_clk_init(NULL); clocksource_probe(); @@ -186,6 +184,7 @@ static void __init zynq_map_io(void) static void __init zynq_irq_init(void) { + zynq_early_slcr_init(); irqchip_init(); } diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c index 26320ebf3493..f0292a30e6f6 100644 --- a/arch/arm/mach-zynq/slcr.c +++ b/arch/arm/mach-zynq/slcr.c @@ -28,6 +28,7 @@ #define SLCR_A9_CPU_RST_CTRL_OFFSET 0x244 /* CPU Software Reset Control */ #define SLCR_REBOOT_STATUS_OFFSET 0x258 /* PS Reboot Status */ #define SLCR_PSS_IDCODE 0x530 /* PS IDCODE */ +#define SLCR_L2C_RAM 0xA1C /* L2C_RAM in AR#54190 */ #define SLCR_UNLOCK_MAGIC 0xDF0D #define SLCR_A9_CPU_CLKSTOP 0x10 @@ -227,6 +228,9 @@ int __init zynq_early_slcr_init(void) /* unlock the SLCR so that registers can be changed */ zynq_slcr_unlock(); + /* See AR#54190 design advisory */ + regmap_update_bits(zynq_slcr_regmap, SLCR_L2C_RAM, 0x70707, 0x20202); + register_restart_handler(&zynq_slcr_restart_nb); pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 8085a8aac812..ffb93db68e9c 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -18,6 +18,7 @@ #include <linux/irq.h> #include <linux/sched_clock.h> #include <plat/time.h> +#include <asm/delay.h> /* * MBus bridge block registers. @@ -188,6 +189,15 @@ orion_time_set_base(void __iomem *_timer_base) timer_base = _timer_base; } +static unsigned long orion_delay_timer_read(void) +{ + return ~readl(timer_base + TIMER0_VAL_OFF); +} + +static struct delay_timer orion_delay_timer = { + .read_current_timer = orion_delay_timer_read, +}; + void __init orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, unsigned int irq, unsigned int tclk) @@ -202,6 +212,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, ticks_per_jiffy = (tclk + HZ/2) / HZ; + orion_delay_timer.freq = tclk; + register_current_timer_delay(&orion_delay_timer); + /* * Set scale and timer for sched_clock. */ diff --git a/arch/arm/plat-pxa/include/plat/dma.h b/arch/arm/plat-pxa/include/plat/dma.h index 28848b344e2d..ceba3e4184fc 100644 --- a/arch/arm/plat-pxa/include/plat/dma.h +++ b/arch/arm/plat-pxa/include/plat/dma.h @@ -95,6 +95,6 @@ static inline int pxad_toggle_reserved_channel(int legacy_channel) } #endif -extern void __init pxa2xx_set_dmac_info(int nb_channels); +extern void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors); #endif /* __PLAT_DMA_H */ diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index cd822d8454c0..307237cfe728 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -27,6 +27,8 @@ $(warning LSE atomics not supported by binutils) endif KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables +KBUILD_CFLAGS += $(call cc-option, -mpc-relative-literal-loads) KBUILD_AFLAGS += $(lseinstr) ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index dd5158eb5872..e5b59ca9debb 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -115,6 +115,7 @@ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi index da7b6e613257..933cba359918 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi @@ -23,9 +23,8 @@ soc0: soc@000000000 { }; }; - dsa: dsa@c7000000 { + dsaf0: dsa@c7000000 { compatible = "hisilicon,hns-dsaf-v1"; - dsa_name = "dsaf0"; mode = "6port-16rss"; interrupt-parent = <&mbigen_dsa>; @@ -127,7 +126,7 @@ soc0: soc@000000000 { eth0: ethernet@0{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <0>; local-mac-address = [00 00 00 01 00 58]; status = "disabled"; @@ -135,14 +134,14 @@ soc0: soc@000000000 { }; eth1: ethernet@1{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <1>; status = "disabled"; dma-coherent; }; eth2: ethernet@2{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <2>; local-mac-address = [00 00 00 01 00 5a]; status = "disabled"; @@ -150,7 +149,7 @@ soc0: soc@000000000 { }; eth3: ethernet@3{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <3>; local-mac-address = [00 00 00 01 00 5b]; status = "disabled"; @@ -158,7 +157,7 @@ soc0: soc@000000000 { }; eth4: ethernet@4{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <4>; local-mac-address = [00 00 00 01 00 5c]; status = "disabled"; @@ -166,7 +165,7 @@ soc0: soc@000000000 { }; eth5: ethernet@5{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <5>; local-mac-address = [00 00 00 01 00 5d]; status = "disabled"; @@ -174,7 +173,7 @@ soc0: soc@000000000 { }; eth6: ethernet@6{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <6>; local-mac-address = [00 00 00 01 00 5e]; status = "disabled"; @@ -182,7 +181,7 @@ soc0: soc@000000000 { }; eth7: ethernet@7{ compatible = "hisilicon,hns-nic-v1"; - ae-name = "dsaf0"; + ae-handle = <&dsaf0>; port-id = <7>; local-mac-address = [00 00 00 01 00 5f]; status = "disabled"; diff --git a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts index 7dfe1c085966..62f33fc84e3e 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts +++ b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts @@ -12,6 +12,8 @@ rtc1 = "/rtc@0,7000e000"; }; + chosen { }; + memory { device_type = "memory"; reg = <0x0 0x80000000 0x0 0x80000000>; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 18ca9fb9e65f..86581f793e39 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -16,7 +16,6 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y -CONFIG_MEMCG_KMEM=y CONFIG_CGROUP_HUGETLB=y # CONFIG_UTS_NS is not set # CONFIG_IPC_NS is not set @@ -37,15 +36,13 @@ CONFIG_ARCH_EXYNOS7=y CONFIG_ARCH_LAYERSCAPE=y CONFIG_ARCH_HISI=y CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_QCOM=y CONFIG_ARCH_ROCKCHIP=y CONFIG_ARCH_SEATTLE=y CONFIG_ARCH_RENESAS=y CONFIG_ARCH_R8A7795=y CONFIG_ARCH_STRATIX10=y CONFIG_ARCH_TEGRA=y -CONFIG_ARCH_TEGRA_132_SOC=y -CONFIG_ARCH_TEGRA_210_SOC=y -CONFIG_ARCH_QCOM=y CONFIG_ARCH_SPRD=y CONFIG_ARCH_THUNDER=y CONFIG_ARCH_UNIPHIER=y @@ -54,14 +51,19 @@ CONFIG_ARCH_XGENE=y CONFIG_ARCH_ZYNQMP=y CONFIG_PCI=y CONFIG_PCI_MSI=y +CONFIG_PCI_IOV=y +CONFIG_PCI_RCAR_GEN2_PCIE=y CONFIG_PCI_HOST_GENERIC=y CONFIG_PCI_XGENE=y -CONFIG_SMP=y +CONFIG_PCI_LAYERSCAPE=y +CONFIG_PCI_HISI=y +CONFIG_PCIE_QCOM=y CONFIG_SCHED_MC=y CONFIG_PREEMPT=y CONFIG_KSM=y CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_CMA=y +CONFIG_XEN=y CONFIG_CMDLINE="console=ttyAMA0" # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y @@ -100,7 +102,11 @@ CONFIG_PATA_OF_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_TUN=y CONFIG_VIRTIO_NET=y +CONFIG_AMD_XGBE=y CONFIG_NET_XGENE=y +CONFIG_E1000E=y +CONFIG_IGB=y +CONFIG_IGBVF=y CONFIG_SKY2=y CONFIG_RAVB=y CONFIG_SMC91X=y @@ -117,25 +123,23 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_8250_MT6577=y CONFIG_SERIAL_8250_UNIPHIER=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_SAMSUNG=y -CONFIG_SERIAL_SAMSUNG_UARTS_4=y -CONFIG_SERIAL_SAMSUNG_UARTS=4 CONFIG_SERIAL_SAMSUNG_CONSOLE=y +CONFIG_SERIAL_TEGRA=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=11 CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_TEGRA=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_VIRTIO_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_I2C=y CONFIG_I2C_QUP=y +CONFIG_I2C_UNIPHIER_F=y CONFIG_I2C_RCAR=y CONFIG_SPI=y CONFIG_SPI_PL022=y @@ -176,8 +180,6 @@ CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_TEGRA=y CONFIG_MMC_SPI=y CONFIG_MMC_DW=y -CONFIG_MMC_DW_IDMAC=y -CONFIG_MMC_DW_PLTFM=y CONFIG_MMC_DW_EXYNOS=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y @@ -187,28 +189,33 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_PL031=y CONFIG_RTC_DRV_XGENE=y CONFIG_DMADEVICES=y -CONFIG_RCAR_DMAC=y CONFIG_QCOM_BAM_DMA=y CONFIG_TEGRA20_APB_DMA=y +CONFIG_RCAR_DMAC=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_MMIO=y +CONFIG_XEN_GNTDEV=y +CONFIG_XEN_GRANT_DEV_ALLOC=y CONFIG_COMMON_CLK_CS2000_CP=y CONFIG_COMMON_CLK_QCOM=y CONFIG_MSM_GCC_8916=y CONFIG_HWSPINLOCK_QCOM=y -# CONFIG_IOMMU_SUPPORT is not set +CONFIG_ARM_SMMU=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD=y CONFIG_QCOM_SMD_RPM=y +CONFIG_ARCH_TEGRA_132_SOC=y +CONFIG_ARCH_TEGRA_210_SOC=y +CONFIG_HISILICON_IRQ_MBIGEN=y CONFIG_PHY_XGENE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_QUOTA=y @@ -239,6 +246,7 @@ CONFIG_LOCKUP_DETECTOR=y # CONFIG_FTRACE is not set CONFIG_MEMTEST=y CONFIG_SECURITY=y +CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index 007a69fc4f40..5f3ab8c1db55 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -121,6 +121,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; asm volatile("// futex_atomic_cmpxchg_inatomic\n" +ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN) " prfm pstl1strm, %2\n" "1: ldxr %w1, %2\n" " sub %w3, %w1, %w4\n" @@ -137,6 +138,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, " .align 3\n" " .quad 1b, 4b, 2b, 4b\n" " .popsection\n" +ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN) : "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp) : "r" (oldval), "r" (newval), "Ir" (-EFAULT) : "memory"); diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 9b2f5a9d019d..ae615b9d9a55 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -39,6 +39,7 @@ #ifndef __ASSEMBLY__ +#include <linux/personality.h> /* for READ_IMPLIES_EXEC */ #include <asm/pgtable-types.h> extern void __cpu_clear_user_page(void *p, unsigned long user); diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 2d545d7aa80b..bf464de33f52 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -67,11 +67,11 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) #define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) -#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRnE)) -#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) -#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_NC)) -#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_WT)) -#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL)) +#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE)) +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE)) +#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC)) +#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT)) +#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) @@ -81,7 +81,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #define PAGE_KERNEL __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE) #define PAGE_KERNEL_RO __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY) -#define PAGE_KERNEL_ROX __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY) +#define PAGE_KERNEL_ROX __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY) #define PAGE_KERNEL_EXEC __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE) #define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT) @@ -153,6 +153,7 @@ extern struct page *empty_zero_page; #define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE)) #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) #define pte_cont(pte) (!!(pte_val(pte) & PTE_CONT)) +#define pte_user(pte) (!!(pte_val(pte) & PTE_USER)) #ifdef CONFIG_ARM64_HW_AFDBM #define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY)) @@ -163,8 +164,6 @@ extern struct page *empty_zero_page; #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) -#define pte_valid_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) #define pte_valid_not_user(pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) #define pte_valid_young(pte) \ @@ -278,13 +277,13 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { - if (pte_valid_user(pte)) { - if (!pte_special(pte) && pte_exec(pte)) - __sync_icache_dcache(pte, addr); + if (pte_valid(pte)) { if (pte_sw_dirty(pte) && pte_write(pte)) pte_val(pte) &= ~PTE_RDONLY; else pte_val(pte) |= PTE_RDONLY; + if (pte_user(pte) && pte_exec(pte) && !pte_special(pte)) + __sync_icache_dcache(pte, addr); } /* diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index ffe9c2b6431b..917d98108b3f 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -514,9 +514,14 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems #endif /* EL2 debug */ + mrs x0, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer + sbfx x0, x0, #8, #4 + cmp x0, #1 + b.lt 4f // Skip if no PMU present mrs x0, pmcr_el0 // Disable debug access traps ubfx x0, x0, #11, #5 // to EL2 and allow access to msr mdcr_el2, x0 // all PMU counters from EL1 +4: /* Stage-2 translation */ msr vttbr_el2, xzr diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h index bc2abb8b1599..999633bd7294 100644 --- a/arch/arm64/kernel/image.h +++ b/arch/arm64/kernel/image.h @@ -65,6 +65,16 @@ #ifdef CONFIG_EFI /* + * Prevent the symbol aliases below from being emitted into the kallsyms + * table, by forcing them to be absolute symbols (which are conveniently + * ignored by scripts/kallsyms) rather than section relative symbols. + * The distinction is only relevant for partial linking, and only for symbols + * that are defined within a section declaration (which is not the case for + * the definitions below) so the resulting values will be identical. + */ +#define KALLSYMS_HIDE(sym) ABSOLUTE(sym) + +/* * The EFI stub has its own symbol namespace prefixed by __efistub_, to * isolate it from the kernel proper. The following symbols are legally * accessed by the stub, so provide some aliases to make them accessible. @@ -73,25 +83,25 @@ * linked at. The routines below are all implemented in assembler in a * position independent manner */ -__efistub_memcmp = __pi_memcmp; -__efistub_memchr = __pi_memchr; -__efistub_memcpy = __pi_memcpy; -__efistub_memmove = __pi_memmove; -__efistub_memset = __pi_memset; -__efistub_strlen = __pi_strlen; -__efistub_strcmp = __pi_strcmp; -__efistub_strncmp = __pi_strncmp; -__efistub___flush_dcache_area = __pi___flush_dcache_area; +__efistub_memcmp = KALLSYMS_HIDE(__pi_memcmp); +__efistub_memchr = KALLSYMS_HIDE(__pi_memchr); +__efistub_memcpy = KALLSYMS_HIDE(__pi_memcpy); +__efistub_memmove = KALLSYMS_HIDE(__pi_memmove); +__efistub_memset = KALLSYMS_HIDE(__pi_memset); +__efistub_strlen = KALLSYMS_HIDE(__pi_strlen); +__efistub_strcmp = KALLSYMS_HIDE(__pi_strcmp); +__efistub_strncmp = KALLSYMS_HIDE(__pi_strncmp); +__efistub___flush_dcache_area = KALLSYMS_HIDE(__pi___flush_dcache_area); #ifdef CONFIG_KASAN -__efistub___memcpy = __pi_memcpy; -__efistub___memmove = __pi_memmove; -__efistub___memset = __pi_memset; +__efistub___memcpy = KALLSYMS_HIDE(__pi_memcpy); +__efistub___memmove = KALLSYMS_HIDE(__pi_memmove); +__efistub___memset = KALLSYMS_HIDE(__pi_memset); #endif -__efistub__text = _text; -__efistub__end = _end; -__efistub__edata = _edata; +__efistub__text = KALLSYMS_HIDE(_text); +__efistub__end = KALLSYMS_HIDE(_end); +__efistub__edata = KALLSYMS_HIDE(_edata); #endif diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c index 5a22a119a74c..0adbebbc2803 100644 --- a/arch/arm64/mm/dump.c +++ b/arch/arm64/mm/dump.c @@ -46,7 +46,7 @@ enum address_markers_idx { PCI_START_NR, PCI_END_NR, MODULES_START_NR, - MODUELS_END_NR, + MODULES_END_NR, KERNEL_SPACE_NR, }; diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index cf038c7d9fa9..cab7a5be40aa 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -120,6 +120,7 @@ static void __init cpu_set_ttbr1(unsigned long ttbr1) void __init kasan_init(void) { struct memblock_region *reg; + int i; /* * We are going to perform proper setup of shadow memory. @@ -155,6 +156,14 @@ void __init kasan_init(void) pfn_to_nid(virt_to_pfn(start))); } + /* + * KAsan may reuse the contents of kasan_zero_pte directly, so we + * should make sure that it maps the zero page read-only. + */ + for (i = 0; i < PTRS_PER_PTE; i++) + set_pte(&kasan_zero_pte[i], + pfn_pte(virt_to_pfn(kasan_zero_page), PAGE_KERNEL_RO)); + memset(kasan_zero_page, 0, PAGE_SIZE); cpu_set_ttbr1(__pa(swapper_pg_dir)); flush_tlb_all(); diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index 3571c7309c5e..0795c3a36d8f 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -14,6 +14,7 @@ #include <linux/mm.h> #include <linux/module.h> #include <linux/sched.h> +#include <linux/vmalloc.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> @@ -44,6 +45,7 @@ static int change_memory_common(unsigned long addr, int numpages, unsigned long end = start + size; int ret; struct page_change_data data; + struct vm_struct *area; if (!PAGE_ALIGNED(addr)) { start &= PAGE_MASK; @@ -51,11 +53,27 @@ static int change_memory_common(unsigned long addr, int numpages, WARN_ON_ONCE(1); } - if (start < MODULES_VADDR || start >= MODULES_END) + /* + * Kernel VA mappings are always live, and splitting live section + * mappings into page mappings may cause TLB conflicts. This means + * we have to ensure that changing the permission bits of the range + * we are operating on does not result in such splitting. + * + * Let's restrict ourselves to mappings created by vmalloc (or vmap). + * Those are guaranteed to consist entirely of page mappings, and + * splitting is never needed. + * + * So check whether the [addr, addr + size) interval is entirely + * covered by precisely one VM area that has the VM_ALLOC flag set. + */ + area = find_vm_area((void *)addr); + if (!area || + end > (unsigned long)area->addr + area->size || + !(area->flags & VM_ALLOC)) return -EINVAL; - if (end < MODULES_VADDR || end >= MODULES_END) - return -EINVAL; + if (!numpages) + return 0; data.set_mask = set_mask; data.clear_mask = clear_mask; diff --git a/arch/arm64/mm/proc-macros.S b/arch/arm64/mm/proc-macros.S index 146bd99a7532..e6a30e1268a8 100644 --- a/arch/arm64/mm/proc-macros.S +++ b/arch/arm64/mm/proc-macros.S @@ -84,3 +84,15 @@ b.lo 9998b dsb \domain .endm + +/* + * reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present + */ + .macro reset_pmuserenr_el0, tmpreg + mrs \tmpreg, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer + sbfx \tmpreg, \tmpreg, #8, #4 + cmp \tmpreg, #1 // Skip if no PMU present + b.lt 9000f + msr pmuserenr_el0, xzr // Disable PMU access from EL0 +9000: + .endm diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index a3d867e723b4..c164d2cb35c0 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -117,7 +117,7 @@ ENTRY(cpu_do_resume) */ ubfx x11, x11, #1, #1 msr oslar_el1, x11 - msr pmuserenr_el0, xzr // Disable PMU access from EL0 + reset_pmuserenr_el0 x0 // Disable PMU access from EL0 mov x0, x12 dsb nsh // Make sure local tlb invalidation completed isb @@ -154,7 +154,7 @@ ENTRY(__cpu_setup) msr cpacr_el1, x0 // Enable FP/ASIMD mov x0, #1 << 12 // Reset mdscr_el1 and disable msr mdscr_el1, x0 // access to the DCC from EL0 - msr pmuserenr_el0, xzr // Disable PMU access from EL0 + reset_pmuserenr_el0 x0 // Disable PMU access from EL0 /* * Memory region attributes for LPAE: * diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 836ac5a963c8..2841c0a3fd3b 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -276,6 +276,7 @@ source "kernel/Kconfig.preempt" config SMP bool "Symmetric multi-processing support" + depends on MMU ---help--- This enables support for systems with more than one CPU. If you have a system with only one CPU, say N. If you have a system with more diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index 5f2bc1e10eae..05757aed016c 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c @@ -19,6 +19,8 @@ #include <bcm63xx_nvram.h> +#define BCM63XX_DEFAULT_PSI_SIZE 64 + static struct bcm963xx_nvram nvram; static int mac_addr_used; @@ -85,3 +87,12 @@ int bcm63xx_nvram_get_mac_address(u8 *mac) return 0; } EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); + +int bcm63xx_nvram_get_psi_size(void) +{ + if (nvram.psi_size > 0) + return nvram.psi_size; + + return BCM63XX_DEFAULT_PSI_SIZE; +} +EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size); diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 4e0b6bc1165e..348df49dcc9f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h @@ -30,4 +30,6 @@ u8 *bcm63xx_nvram_get_name(void); */ int bcm63xx_nvram_get_mac_address(u8 *mac); +int bcm63xx_nvram_get_psi_size(void); + #endif /* BCM63XX_NVRAM_H */ diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 06f17e778c27..8d1c8162f0c1 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -50,7 +50,9 @@ * set of bits not changed in pmd_modify. */ #define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ - _PAGE_ACCESSED | _PAGE_THP_HUGE) + _PAGE_ACCESSED | _PAGE_THP_HUGE | _PAGE_PTE | \ + _PAGE_SOFT_DIRTY) + #ifdef CONFIG_PPC_64K_PAGES #include <asm/book3s/64/hash-64k.h> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 8204b0c393aa..8d1c41d28318 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -223,7 +223,6 @@ static inline pte_t *pmdp_ptep(pmd_t *pmd) #define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd)) #define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) #define pmd_young(pmd) pte_young(pmd_pte(pmd)) -#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) #define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd))) #define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 271fefbbe521..9d08d8cbed1a 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -38,8 +38,7 @@ #define KVM_MAX_VCPUS NR_CPUS #define KVM_MAX_VCORES NR_CPUS -#define KVM_USER_MEM_SLOTS 32 -#define KVM_MEM_SLOTS_NUM KVM_USER_MEM_SLOTS +#define KVM_USER_MEM_SLOTS 512 #ifdef CONFIG_KVM_MMIO #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 5654ece02c0d..3fa9df70aa20 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -383,3 +383,4 @@ SYSCALL(ni_syscall) SYSCALL(ni_syscall) SYSCALL(ni_syscall) SYSCALL(mlock2) +SYSCALL(copy_file_range) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 6a5ace5fa0c8..1f2594d45605 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -12,7 +12,7 @@ #include <uapi/asm/unistd.h> -#define NR_syscalls 379 +#define NR_syscalls 380 #define __NR__exit __NR_exit diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index 12a05652377a..940290d45b08 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h @@ -389,5 +389,6 @@ #define __NR_userfaultfd 364 #define __NR_membarrier 365 #define __NR_mlock2 378 +#define __NR_copy_file_range 379 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 8654cb166c19..ca9e5371930e 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -883,32 +883,29 @@ void eeh_pe_restore_bars(struct eeh_pe *pe) const char *eeh_pe_loc_get(struct eeh_pe *pe) { struct pci_bus *bus = eeh_pe_bus_get(pe); - struct device_node *dn = pci_bus_to_OF_node(bus); + struct device_node *dn; const char *loc = NULL; - if (!dn) - goto out; + while (bus) { + dn = pci_bus_to_OF_node(bus); + if (!dn) { + bus = bus->parent; + continue; + } - /* PHB PE or root PE ? */ - if (pci_is_root_bus(bus)) { - loc = of_get_property(dn, "ibm,loc-code", NULL); - if (!loc) + if (pci_is_root_bus(bus)) loc = of_get_property(dn, "ibm,io-base-loc-code", NULL); + else + loc = of_get_property(dn, "ibm,slot-location-code", + NULL); + if (loc) - goto out; + return loc; - /* Check the root port */ - dn = dn->child; - if (!dn) - goto out; + bus = bus->parent; } - loc = of_get_property(dn, "ibm,loc-code", NULL); - if (!loc) - loc = of_get_property(dn, "ibm,slot-location-code", NULL); - -out: - return loc ? loc : "N/A"; + return "N/A"; } /** diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index db475d41b57a..f28754c497e5 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -701,31 +701,3 @@ _GLOBAL(kexec_sequence) li r5,0 blr /* image->start(physid, image->start, 0); */ #endif /* CONFIG_KEXEC */ - -#ifdef CONFIG_MODULES -#if defined(_CALL_ELF) && _CALL_ELF == 2 - -#ifdef CONFIG_MODVERSIONS -.weak __crc_TOC. -.section "___kcrctab+TOC.","a" -.globl __kcrctab_TOC. -__kcrctab_TOC.: - .llong __crc_TOC. -#endif - -/* - * Export a fake .TOC. since both modpost and depmod will complain otherwise. - * Both modpost and depmod strip the leading . so we do the same here. - */ -.section "__ksymtab_strings","a" -__kstrtab_TOC.: - .asciz "TOC." - -.section "___ksymtab+TOC.","a" -/* This symbol name is important: it's used by modpost to find exported syms */ -.globl __ksymtab_TOC. -__ksymtab_TOC.: - .llong 0 /* .value */ - .llong __kstrtab_TOC. -#endif /* ELFv2 */ -#endif /* MODULES */ diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 59663af9315f..ac64ffdb52c8 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -326,7 +326,10 @@ static void dedotify_versions(struct modversion_info *vers, } } -/* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */ +/* + * Undefined symbols which refer to .funcname, hack to funcname. Make .TOC. + * seem to be defined (value set later). + */ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) { unsigned int i; @@ -334,8 +337,11 @@ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) for (i = 1; i < numsyms; i++) { if (syms[i].st_shndx == SHN_UNDEF) { char *name = strtab + syms[i].st_name; - if (name[0] == '.') + if (name[0] == '.') { + if (strcmp(name+1, "TOC.") == 0) + syms[i].st_shndx = SHN_ABS; memmove(name, name+1, strlen(name)); + } } } } @@ -351,7 +357,7 @@ static Elf64_Sym *find_dot_toc(Elf64_Shdr *sechdrs, numsyms = sechdrs[symindex].sh_size / sizeof(Elf64_Sym); for (i = 1; i < numsyms; i++) { - if (syms[i].st_shndx == SHN_UNDEF + if (syms[i].st_shndx == SHN_ABS && strcmp(strtab + syms[i].st_name, "TOC.") == 0) return &syms[i]; } diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 774a253ca4e1..9bf7031a67ff 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -377,15 +377,12 @@ no_seg_found: static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb) { - struct kvmppc_vcpu_book3s *vcpu_book3s; u64 esid, esid_1t; int slb_nr; struct kvmppc_slb *slbe; dprintk("KVM MMU: slbmte(0x%llx, 0x%llx)\n", rs, rb); - vcpu_book3s = to_book3s(vcpu); - esid = GET_ESID(rb); esid_1t = GET_ESID_1T(rb); slb_nr = rb & 0xfff; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index cff207b72c46..baeddb06811d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -833,6 +833,24 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->stat.sum_exits++; + /* + * This can happen if an interrupt occurs in the last stages + * of guest entry or the first stages of guest exit (i.e. after + * setting paca->kvm_hstate.in_guest to KVM_GUEST_MODE_GUEST_HV + * and before setting it to KVM_GUEST_MODE_HOST_HV). + * That can happen due to a bug, or due to a machine check + * occurring at just the wrong time. + */ + if (vcpu->arch.shregs.msr & MSR_HV) { + printk(KERN_EMERG "KVM trap in HV mode!\n"); + printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n", + vcpu->arch.trap, kvmppc_get_pc(vcpu), + vcpu->arch.shregs.msr); + kvmppc_dump_regs(vcpu); + run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + run->hw.hardware_exit_reason = vcpu->arch.trap; + return RESUME_HOST; + } run->exit_reason = KVM_EXIT_UNKNOWN; run->ready_for_interrupt_injection = 1; switch (vcpu->arch.trap) { diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 3c6badcd53ef..6ee26de9a1de 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -2153,7 +2153,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) /* Emulate H_SET_DABR/X on P8 for the sake of compat mode guests */ 2: rlwimi r5, r4, 5, DAWRX_DR | DAWRX_DW - rlwimi r5, r4, 1, DAWRX_WT + rlwimi r5, r4, 2, DAWRX_WT clrrdi r4, r4, 3 std r4, VCPU_DAWR(r3) std r5, VCPU_DAWRX(r3) @@ -2404,6 +2404,8 @@ machine_check_realmode: * guest as machine check causing guest to crash. */ ld r11, VCPU_MSR(r9) + rldicl. r0, r11, 64-MSR_HV_LG, 63 /* check if it happened in HV mode */ + bne mc_cont /* if so, exit to host */ andi. r10, r11, MSR_RI /* check for unrecoverable exception */ beq 1f /* Deliver a machine check to guest */ ld r10, VCPU_PC(r9) diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 6fd2405c7f4a..a3b182dcb823 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -919,21 +919,17 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) r = -ENXIO; break; } - vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval; + val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0]; break; case KVM_REG_PPC_VSCR: if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { r = -ENXIO; break; } - vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val); + val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]); break; case KVM_REG_PPC_VRSAVE: - if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { - r = -ENXIO; - break; - } - vcpu->arch.vrsave = set_reg_val(reg->id, val); + val = get_reg_val(reg->id, vcpu->arch.vrsave); break; #endif /* CONFIG_ALTIVEC */ default: @@ -974,17 +970,21 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) r = -ENXIO; break; } - val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0]; + vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval; break; case KVM_REG_PPC_VSCR: if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { r = -ENXIO; break; } - val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]); + vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val); break; case KVM_REG_PPC_VRSAVE: - val = get_reg_val(reg->id, vcpu->arch.vrsave); + if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { + r = -ENXIO; + break; + } + vcpu->arch.vrsave = set_reg_val(reg->id, val); break; #endif /* CONFIG_ALTIVEC */ default: diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 22d94c3e6fc4..d0f0a514b04e 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -560,12 +560,12 @@ subsys_initcall(add_system_ram_resources); */ int devmem_is_allowed(unsigned long pfn) { + if (page_is_rtas_user_buf(pfn)) + return 1; if (iomem_is_exclusive(PFN_PHYS(pfn))) return 0; if (!page_is_ram(pfn)) return 1; - if (page_is_rtas_user_buf(pfn)) - return 1; return 0; } #endif /* CONFIG_STRICT_DEVMEM */ diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 7d5e295255b7..9958ba8bf0d2 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c @@ -816,7 +816,7 @@ static struct power_pmu power8_pmu = { .get_constraint = power8_get_constraint, .get_alternatives = power8_get_alternatives, .disable_pmc = power8_disable_pmc, - .flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_ARCH_207S, + .flags = PPMU_HAS_SIER | PPMU_ARCH_207S, .n_generic = ARRAY_SIZE(power8_generic_events), .generic_events = power8_generic_events, .cache_events = &power8_cache_events, diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h index 16aa0c779e07..595a275c36f8 100644 --- a/arch/s390/include/asm/irqflags.h +++ b/arch/s390/include/asm/irqflags.h @@ -8,6 +8,8 @@ #include <linux/types.h> +#define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8)) + /* store then OR system mask. */ #define __arch_local_irq_stosm(__or) \ ({ \ @@ -54,14 +56,17 @@ static inline notrace void arch_local_irq_enable(void) __arch_local_irq_stosm(0x03); } +/* This only restores external and I/O interrupt state */ static inline notrace void arch_local_irq_restore(unsigned long flags) { - __arch_local_irq_ssm(flags); + /* only disabled->disabled and disabled->enabled is valid */ + if (flags & ARCH_IRQ_ENABLED) + arch_local_irq_enable(); } static inline notrace bool arch_irqs_disabled_flags(unsigned long flags) { - return !(flags & (3UL << (BITS_PER_LONG - 8))); + return !(flags & ARCH_IRQ_ENABLED); } static inline notrace bool arch_irqs_disabled(void) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 6742414dbd6f..8959ebb6d2c9 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -546,7 +546,6 @@ struct kvm_vcpu_arch { struct kvm_s390_sie_block *sie_block; unsigned int host_acrs[NUM_ACRS]; struct fpu host_fpregs; - struct fpu guest_fpregs; struct kvm_s390_local_interrupt local_int; struct hrtimer ckc_timer; struct kvm_s390_pgm_info pgm; diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h index 1a9a98de5bde..69aa18be61af 100644 --- a/arch/s390/include/asm/pci_io.h +++ b/arch/s390/include/asm/pci_io.h @@ -8,10 +8,13 @@ #include <asm/pci_insn.h> /* I/O Map */ -#define ZPCI_IOMAP_MAX_ENTRIES 0x7fff -#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000ULL -#define ZPCI_IOMAP_ADDR_IDX_MASK 0x7fff000000000000ULL -#define ZPCI_IOMAP_ADDR_OFF_MASK 0x0000ffffffffffffULL +#define ZPCI_IOMAP_SHIFT 48 +#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL +#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) +#define ZPCI_IOMAP_MAX_ENTRIES \ + ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT)) +#define ZPCI_IOMAP_ADDR_IDX_MASK \ + (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE) struct zpci_iomap_entry { u32 fh; @@ -21,8 +24,9 @@ struct zpci_iomap_entry { extern struct zpci_iomap_entry *zpci_iomap_start; +#define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT)) #define ZPCI_IDX(addr) \ - (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> 48) + (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT) #define ZPCI_OFFSET(addr) \ ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index f16debf6a612..1c4fe129486d 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -166,14 +166,14 @@ extern __vector128 init_task_fpu_regs[__NUM_VXRS]; */ #define start_thread(regs, new_psw, new_stackp) do { \ regs->psw.mask = PSW_USER_BITS | PSW_MASK_EA | PSW_MASK_BA; \ - regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->psw.addr = new_psw; \ regs->gprs[15] = new_stackp; \ execve_tail(); \ } while (0) #define start_thread31(regs, new_psw, new_stackp) do { \ regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \ - regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->psw.addr = new_psw; \ regs->gprs[15] = new_stackp; \ crst_table_downgrade(current->mm, 1UL << 31); \ execve_tail(); \ diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index f00cd35c8ac4..99bc456cc26a 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -149,7 +149,7 @@ static inline int test_pt_regs_flag(struct pt_regs *regs, int flag) #define arch_has_block_step() (1) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) -#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) +#define instruction_pointer(regs) ((regs)->psw.addr) #define user_stack_pointer(regs)((regs)->gprs[15]) #define profile_pc(regs) instruction_pointer(regs) @@ -161,7 +161,7 @@ static inline long regs_return_value(struct pt_regs *regs) static inline void instruction_pointer_set(struct pt_regs *regs, unsigned long val) { - regs->psw.addr = val | PSW_ADDR_AMODE; + regs->psw.addr = val; } int regs_query_register_offset(const char *name); @@ -171,7 +171,7 @@ unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) { - return regs->gprs[15] & PSW_ADDR_INSN; + return regs->gprs[15]; } #endif /* __ASSEMBLY__ */ diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index 34ec202472c6..ab3aa6875a59 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h @@ -310,7 +310,8 @@ #define __NR_recvmsg 372 #define __NR_shutdown 373 #define __NR_mlock2 374 -#define NR_syscalls 375 +#define __NR_copy_file_range 375 +#define NR_syscalls 376 /* * There are some system calls that are not present on 64 bit, some diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index fac4eeddef91..ae2cda5eee5a 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -177,3 +177,4 @@ COMPAT_SYSCALL_WRAP3(getsockname, int, fd, struct sockaddr __user *, usockaddr, COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len); COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len); COMPAT_SYSCALL_WRAP3(mlock2, unsigned long, start, size_t, len, int, flags); +COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags); diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index a92b39fd0e63..3986c9f62191 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -59,8 +59,6 @@ struct save_area * __init save_area_alloc(bool is_boot_cpu) struct save_area *sa; sa = (void *) memblock_alloc(sizeof(*sa), 8); - if (!sa) - return NULL; if (is_boot_cpu) list_add(&sa->list, &dump_save_areas); else diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 6fca0e46464e..c890a5589e59 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -1470,7 +1470,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, except_str = "*"; else except_str = "-"; - caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN; + caller = (unsigned long) entry->caller; rc += sprintf(out_buf, "%02i %011lld:%06lu %1u %1s %02i %p ", area, (long long)time_spec.tv_sec, time_spec.tv_nsec / 1000, level, except_str, diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index dc8e20473484..02bd02ff648b 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -34,22 +34,21 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) unsigned long addr; while (1) { - sp = sp & PSW_ADDR_INSN; if (sp < low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - addr = sf->gprs[8] & PSW_ADDR_INSN; + addr = sf->gprs[8]; printk("([<%016lx>] %pSR)\n", addr, (void *)addr); /* Follow the backchain. */ while (1) { low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; + sp = sf->back_chain; if (!sp) break; if (sp <= low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - addr = sf->gprs[8] & PSW_ADDR_INSN; + addr = sf->gprs[8]; printk(" [<%016lx>] %pSR\n", addr, (void *)addr); } /* Zero backchain detected, check for interrupt frame. */ @@ -57,7 +56,7 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) if (sp <= low || sp > high - sizeof(*regs)) return sp; regs = (struct pt_regs *) sp; - addr = regs->psw.addr & PSW_ADDR_INSN; + addr = regs->psw.addr; printk(" [<%016lx>] %pSR\n", addr, (void *)addr); low = sp; sp = regs->gprs[15]; diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 20a5caf6d981..c55576bbaa1f 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -252,14 +252,14 @@ static void early_pgm_check_handler(void) unsigned long addr; addr = S390_lowcore.program_old_psw.addr; - fixup = search_exception_tables(addr & PSW_ADDR_INSN); + fixup = search_exception_tables(addr); if (!fixup) disabled_wait(0); /* Disable low address protection before storing into lowcore. */ __ctl_store(cr0, 0, 0); cr0_new = cr0 & ~(1UL << 28); __ctl_load(cr0_new, 0, 0); - S390_lowcore.program_old_psw.addr = extable_fixup(fixup)|PSW_ADDR_AMODE; + S390_lowcore.program_old_psw.addr = extable_fixup(fixup); __ctl_load(cr0, 0, 0); } @@ -268,9 +268,9 @@ static noinline __init void setup_lowcore_early(void) psw_t psw; psw.mask = PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA; - psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_ext_handler; + psw.addr = (unsigned long) s390_base_ext_handler; S390_lowcore.external_new_psw = psw; - psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; + psw.addr = (unsigned long) s390_base_pgm_handler; S390_lowcore.program_new_psw = psw; s390_base_pgm_handler_fn = early_pgm_check_handler; } diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index e0eaf11134b4..0f7bfeba6da6 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -203,7 +203,7 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip) goto out; if (unlikely(atomic_read(¤t->tracing_graph_pause))) goto out; - ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE; + ip -= MCOUNT_INSN_SIZE; trace.func = ip; trace.depth = current->curr_ret_stack + 1; /* Only trace if the calling function expects to. */ diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 0a5a6b661b93..f20abdb5630a 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -2057,12 +2057,12 @@ void s390_reset_system(void) /* Set new machine check handler */ S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT; S390_lowcore.mcck_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler; + (unsigned long) s390_base_mcck_handler; /* Set new program check handler */ S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT; S390_lowcore.program_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler; + (unsigned long) s390_base_pgm_handler; /* * Clear subchannel ID and number to signal new kernel that no CCW or diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 389db56a2208..250f5972536a 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -226,7 +226,7 @@ static void enable_singlestep(struct kprobe_ctlblk *kcb, __ctl_load(per_kprobe, 9, 11); regs->psw.mask |= PSW_MASK_PER; regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT); - regs->psw.addr = ip | PSW_ADDR_AMODE; + regs->psw.addr = ip; } NOKPROBE_SYMBOL(enable_singlestep); @@ -238,7 +238,7 @@ static void disable_singlestep(struct kprobe_ctlblk *kcb, __ctl_load(kcb->kprobe_saved_ctl, 9, 11); regs->psw.mask &= ~PSW_MASK_PER; regs->psw.mask |= kcb->kprobe_saved_imask; - regs->psw.addr = ip | PSW_ADDR_AMODE; + regs->psw.addr = ip; } NOKPROBE_SYMBOL(disable_singlestep); @@ -310,7 +310,7 @@ static int kprobe_handler(struct pt_regs *regs) */ preempt_disable(); kcb = get_kprobe_ctlblk(); - p = get_kprobe((void *)((regs->psw.addr & PSW_ADDR_INSN) - 2)); + p = get_kprobe((void *)(regs->psw.addr - 2)); if (p) { if (kprobe_running()) { @@ -460,7 +460,7 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) break; } - regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE; + regs->psw.addr = orig_ret_address; pop_kprobe(get_kprobe_ctlblk()); kretprobe_hash_unlock(current, &flags); @@ -490,7 +490,7 @@ NOKPROBE_SYMBOL(trampoline_probe_handler); static void resume_execution(struct kprobe *p, struct pt_regs *regs) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); - unsigned long ip = regs->psw.addr & PSW_ADDR_INSN; + unsigned long ip = regs->psw.addr; int fixup = probe_get_fixup_type(p->ainsn.insn); /* Check if the kprobes location is an enabled ftrace caller */ @@ -605,9 +605,9 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr) * In case the user-specified fault handler returned * zero, try to fix up. */ - entry = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); + entry = search_exception_tables(regs->psw.addr); if (entry) { - regs->psw.addr = extable_fixup(entry) | PSW_ADDR_AMODE; + regs->psw.addr = extable_fixup(entry); return 1; } @@ -683,7 +683,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs)); /* setup return addr to the jprobe handler routine */ - regs->psw.addr = (unsigned long) jp->entry | PSW_ADDR_AMODE; + regs->psw.addr = (unsigned long) jp->entry; regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT); /* r15 is the stack pointer */ diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index 61595c1f0a0f..cfcba2dd9bb5 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -74,7 +74,7 @@ static unsigned long guest_is_user_mode(struct pt_regs *regs) static unsigned long instruction_pointer_guest(struct pt_regs *regs) { - return sie_block(regs)->gpsw.addr & PSW_ADDR_INSN; + return sie_block(regs)->gpsw.addr; } unsigned long perf_instruction_pointer(struct pt_regs *regs) @@ -231,29 +231,27 @@ static unsigned long __store_trace(struct perf_callchain_entry *entry, struct pt_regs *regs; while (1) { - sp = sp & PSW_ADDR_INSN; if (sp < low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - perf_callchain_store(entry, sf->gprs[8] & PSW_ADDR_INSN); + perf_callchain_store(entry, sf->gprs[8]); /* Follow the backchain. */ while (1) { low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; + sp = sf->back_chain; if (!sp) break; if (sp <= low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - perf_callchain_store(entry, - sf->gprs[8] & PSW_ADDR_INSN); + perf_callchain_store(entry, sf->gprs[8]); } /* Zero backchain detected, check for interrupt frame. */ sp = (unsigned long) (sf + 1); if (sp <= low || sp > high - sizeof(*regs)) return sp; regs = (struct pt_regs *) sp; - perf_callchain_store(entry, sf->gprs[8] & PSW_ADDR_INSN); + perf_callchain_store(entry, sf->gprs[8]); low = sp; sp = regs->gprs[15]; } diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 114ee8b96f17..2bba7df4ac51 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -56,10 +56,10 @@ unsigned long thread_saved_pc(struct task_struct *tsk) return 0; low = task_stack_page(tsk); high = (struct stack_frame *) task_pt_regs(tsk); - sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN); + sf = (struct stack_frame *) tsk->thread.ksp; if (sf <= low || sf > high) return 0; - sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN); + sf = (struct stack_frame *) sf->back_chain; if (sf <= low || sf > high) return 0; return sf->gprs[8]; @@ -154,7 +154,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, memset(&frame->childregs, 0, sizeof(struct pt_regs)); frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; - frame->childregs.psw.addr = PSW_ADDR_AMODE | + frame->childregs.psw.addr = (unsigned long) kernel_thread_starter; frame->childregs.gprs[9] = new_stackp; /* function */ frame->childregs.gprs[10] = arg; @@ -220,14 +220,14 @@ unsigned long get_wchan(struct task_struct *p) return 0; low = task_stack_page(p); high = (struct stack_frame *) task_pt_regs(p); - sf = (struct stack_frame *) (p->thread.ksp & PSW_ADDR_INSN); + sf = (struct stack_frame *) p->thread.ksp; if (sf <= low || sf > high) return 0; for (count = 0; count < 16; count++) { - sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN); + sf = (struct stack_frame *) sf->back_chain; if (sf <= low || sf > high) return 0; - return_address = sf->gprs[8] & PSW_ADDR_INSN; + return_address = sf->gprs[8]; if (!in_sched_functions(return_address)) return return_address; } diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 01c37b36caf9..49b1c13bf6c9 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -84,7 +84,7 @@ void update_cr_regs(struct task_struct *task) if (test_tsk_thread_flag(task, TIF_UPROBE_SINGLESTEP)) new.control |= PER_EVENT_IFETCH; new.start = 0; - new.end = PSW_ADDR_INSN; + new.end = -1UL; } /* Take care of the PER enablement bit in the PSW. */ @@ -148,7 +148,7 @@ static inline unsigned long __peek_user_per(struct task_struct *child, else if (addr == (addr_t) &dummy->cr11) /* End address of the active per set. */ return test_thread_flag(TIF_SINGLE_STEP) ? - PSW_ADDR_INSN : child->thread.per_user.end; + -1UL : child->thread.per_user.end; else if (addr == (addr_t) &dummy->bits) /* Single-step bit. */ return test_thread_flag(TIF_SINGLE_STEP) ? @@ -495,8 +495,6 @@ long arch_ptrace(struct task_struct *child, long request, } return 0; default: - /* Removing high order bit from addr (only for 31 bit). */ - addr &= PSW_ADDR_INSN; return ptrace_request(child, request, addr, data); } } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index c6878fbbcf13..9220db5c996a 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -301,25 +301,21 @@ static void __init setup_lowcore(void) BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * 4096); lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); lc->restart_psw.mask = PSW_KERNEL_BITS; - lc->restart_psw.addr = - PSW_ADDR_AMODE | (unsigned long) restart_int_handler; + lc->restart_psw.addr = (unsigned long) restart_int_handler; lc->external_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; - lc->external_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) ext_int_handler; + lc->external_new_psw.addr = (unsigned long) ext_int_handler; lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; - lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; + lc->svc_new_psw.addr = (unsigned long) system_call; lc->program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; - lc->program_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) pgm_check_handler; + lc->program_new_psw.addr = (unsigned long) pgm_check_handler; lc->mcck_new_psw.mask = PSW_KERNEL_BITS; - lc->mcck_new_psw.addr = - PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; + lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; - lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; + lc->io_new_psw.addr = (unsigned long) io_int_handler; lc->clock_comparator = -1ULL; lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 028cc46cb82a..d82562cf0a0e 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -331,13 +331,13 @@ static int setup_frame(int sig, struct k_sigaction *ka, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - restorer = (unsigned long) ka->sa.sa_restorer | PSW_ADDR_AMODE; + restorer = (unsigned long) ka->sa.sa_restorer; } else { /* Signal frame without vector registers are short ! */ __u16 __user *svc = (void __user *) frame + frame_size - 2; if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc)) return -EFAULT; - restorer = (unsigned long) svc | PSW_ADDR_AMODE; + restorer = (unsigned long) svc; } /* Set up registers for signal handler */ @@ -347,7 +347,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | (PSW_USER_BITS & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; + regs->psw.addr = (unsigned long) ka->sa.sa_handler; regs->gprs[2] = sig; regs->gprs[3] = (unsigned long) &frame->sc; @@ -394,13 +394,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ksig->ka.sa.sa_flags & SA_RESTORER) { - restorer = (unsigned long) - ksig->ka.sa.sa_restorer | PSW_ADDR_AMODE; + restorer = (unsigned long) ksig->ka.sa.sa_restorer; } else { __u16 __user *svc = &frame->svc_insn; if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc)) return -EFAULT; - restorer = (unsigned long) svc | PSW_ADDR_AMODE; + restorer = (unsigned long) svc; } /* Create siginfo on the signal stack */ @@ -426,7 +425,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | (PSW_USER_BITS & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler | PSW_ADDR_AMODE; + regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler; regs->gprs[2] = ksig->sig; regs->gprs[3] = (unsigned long) &frame->info; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index a13468b9a913..3c65a8eae34d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -623,8 +623,6 @@ void __init smp_save_dump_cpus(void) return; /* Allocate a page as dumping area for the store status sigps */ page = memblock_alloc_base(PAGE_SIZE, PAGE_SIZE, 1UL << 31); - if (!page) - panic("could not allocate memory for save area\n"); /* Set multi-threading state to the previous system. */ pcpu_set_smt(sclp.mtid_prev); boot_cpu_addr = stap(); diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index 1785cd82253c..5acba3cb7220 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c @@ -21,12 +21,11 @@ static unsigned long save_context_stack(struct stack_trace *trace, unsigned long addr; while(1) { - sp &= PSW_ADDR_INSN; if (sp < low || sp > high) return sp; sf = (struct stack_frame *)sp; while(1) { - addr = sf->gprs[8] & PSW_ADDR_INSN; + addr = sf->gprs[8]; if (!trace->skip) trace->entries[trace->nr_entries++] = addr; else @@ -34,7 +33,7 @@ static unsigned long save_context_stack(struct stack_trace *trace, if (trace->nr_entries >= trace->max_entries) return sp; low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; + sp = sf->back_chain; if (!sp) break; if (sp <= low || sp > high - sizeof(*sf)) @@ -46,7 +45,7 @@ static unsigned long save_context_stack(struct stack_trace *trace, if (sp <= low || sp > high - sizeof(*regs)) return sp; regs = (struct pt_regs *)sp; - addr = regs->psw.addr & PSW_ADDR_INSN; + addr = regs->psw.addr; if (savesched || !in_sched_functions(addr)) { if (!trace->skip) trace->entries[trace->nr_entries++] = addr; @@ -65,7 +64,7 @@ void save_stack_trace(struct stack_trace *trace) register unsigned long sp asm ("15"); unsigned long orig_sp, new_sp; - orig_sp = sp & PSW_ADDR_INSN; + orig_sp = sp; new_sp = save_context_stack(trace, orig_sp, S390_lowcore.panic_stack - PAGE_SIZE, S390_lowcore.panic_stack, 1); @@ -86,7 +85,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) { unsigned long sp, low, high; - sp = tsk->thread.ksp & PSW_ADDR_INSN; + sp = tsk->thread.ksp; low = (unsigned long) task_stack_page(tsk); high = (unsigned long) task_pt_regs(tsk); save_context_stack(trace, sp, low, high, 0); diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 5378c3ea1b98..293d8b98fd52 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -383,3 +383,4 @@ SYSCALL(sys_recvfrom,compat_sys_recvfrom) SYSCALL(sys_recvmsg,compat_sys_recvmsg) SYSCALL(sys_shutdown,sys_shutdown) SYSCALL(sys_mlock2,compat_sys_mlock2) +SYSCALL(sys_copy_file_range,compat_sys_copy_file_range) /* 375 */ diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index d69d648759c9..017eb03daee2 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -32,8 +32,7 @@ static inline void __user *get_trap_ip(struct pt_regs *regs) address = *(unsigned long *)(current->thread.trap_tdb + 24); else address = regs->psw.addr; - return (void __user *) - ((address - (regs->int_code >> 16)) & PSW_ADDR_INSN); + return (void __user *) (address - (regs->int_code >> 16)); } static inline void report_user_fault(struct pt_regs *regs, int signr) @@ -46,7 +45,7 @@ static inline void report_user_fault(struct pt_regs *regs, int signr) return; printk("User process fault: interruption code %04x ilc:%d ", regs->int_code & 0xffff, regs->int_code >> 17); - print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); + print_vma_addr("in ", regs->psw.addr); printk("\n"); show_regs(regs); } @@ -69,13 +68,13 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str) report_user_fault(regs, si_signo); } else { const struct exception_table_entry *fixup; - fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); + fixup = search_exception_tables(regs->psw.addr); if (fixup) - regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE; + regs->psw.addr = extable_fixup(fixup); else { enum bug_trap_type btt; - btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); + btt = report_bug(regs->psw.addr, regs); if (btt == BUG_TRAP_TYPE_WARN) return; die(regs, str); diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 5fce52cf0e57..5ea5af3c7db7 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -29,6 +29,7 @@ config KVM select HAVE_KVM_IRQFD select HAVE_KVM_IRQ_ROUTING select SRCU + select KVM_VFIO ---help--- Support hosting paravirtualized guest machines using the SIE virtualization capability on the mainframe. This should work diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile index b3b553469650..d42fa38c2429 100644 --- a/arch/s390/kvm/Makefile +++ b/arch/s390/kvm/Makefile @@ -7,7 +7,7 @@ # as published by the Free Software Foundation. KVM := ../../../virt/kvm -common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o +common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o $(KVM)/vfio.o ccflags-y := -Ivirt/kvm -Iarch/s390/kvm diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index 47518a324d75..d697312ce9ee 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c @@ -116,7 +116,7 @@ static void enable_all_hw_wp(struct kvm_vcpu *vcpu) if (*cr9 & PER_EVENT_STORE && *cr9 & PER_CONTROL_ALTERATION) { *cr9 &= ~PER_CONTROL_ALTERATION; *cr10 = 0; - *cr11 = PSW_ADDR_INSN; + *cr11 = -1UL; } else { *cr9 &= ~PER_CONTROL_ALTERATION; *cr9 |= PER_EVENT_STORE; @@ -159,7 +159,7 @@ void kvm_s390_patch_guest_per_regs(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->gcr[0] &= ~0x800ul; vcpu->arch.sie_block->gcr[9] |= PER_EVENT_IFETCH; vcpu->arch.sie_block->gcr[10] = 0; - vcpu->arch.sie_block->gcr[11] = PSW_ADDR_INSN; + vcpu->arch.sie_block->gcr[11] = -1UL; } if (guestdbg_hw_bp_enabled(vcpu)) { diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 835d60bedb54..4af21c771f9b 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1423,44 +1423,18 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) return 0; } -/* - * Backs up the current FP/VX register save area on a particular - * destination. Used to switch between different register save - * areas. - */ -static inline void save_fpu_to(struct fpu *dst) -{ - dst->fpc = current->thread.fpu.fpc; - dst->regs = current->thread.fpu.regs; -} - -/* - * Switches the FP/VX register save area from which to lazy - * restore register contents. - */ -static inline void load_fpu_from(struct fpu *from) -{ - current->thread.fpu.fpc = from->fpc; - current->thread.fpu.regs = from->regs; -} - void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { /* Save host register state */ save_fpu_regs(); - save_fpu_to(&vcpu->arch.host_fpregs); - - if (test_kvm_facility(vcpu->kvm, 129)) { - current->thread.fpu.fpc = vcpu->run->s.regs.fpc; - /* - * Use the register save area in the SIE-control block - * for register restore and save in kvm_arch_vcpu_put() - */ - current->thread.fpu.vxrs = - (__vector128 *)&vcpu->run->s.regs.vrs; - } else - load_fpu_from(&vcpu->arch.guest_fpregs); + vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc; + vcpu->arch.host_fpregs.regs = current->thread.fpu.regs; + /* Depending on MACHINE_HAS_VX, data stored to vrs either + * has vector register or floating point register format. + */ + current->thread.fpu.regs = vcpu->run->s.regs.vrs; + current->thread.fpu.fpc = vcpu->run->s.regs.fpc; if (test_fp_ctl(current->thread.fpu.fpc)) /* User space provided an invalid FPC, let's clear it */ current->thread.fpu.fpc = 0; @@ -1476,19 +1450,13 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) atomic_andnot(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); gmap_disable(vcpu->arch.gmap); + /* Save guest register state */ save_fpu_regs(); + vcpu->run->s.regs.fpc = current->thread.fpu.fpc; - if (test_kvm_facility(vcpu->kvm, 129)) - /* - * kvm_arch_vcpu_load() set up the register save area to - * the &vcpu->run->s.regs.vrs and, thus, the vector registers - * are already saved. Only the floating-point control must be - * copied. - */ - vcpu->run->s.regs.fpc = current->thread.fpu.fpc; - else - save_fpu_to(&vcpu->arch.guest_fpregs); - load_fpu_from(&vcpu->arch.host_fpregs); + /* Restore host register state */ + current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc; + current->thread.fpu.regs = vcpu->arch.host_fpregs.regs; save_access_regs(vcpu->run->s.regs.acrs); restore_access_regs(vcpu->arch.host_acrs); @@ -1506,8 +1474,9 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64)); vcpu->arch.sie_block->gcr[0] = 0xE0UL; vcpu->arch.sie_block->gcr[14] = 0xC2000000UL; - vcpu->arch.guest_fpregs.fpc = 0; - asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc)); + /* make sure the new fpc will be lazily loaded */ + save_fpu_regs(); + current->thread.fpu.fpc = 0; vcpu->arch.sie_block->gbea = 1; vcpu->arch.sie_block->pp = 0; vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; @@ -1648,17 +1617,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, vcpu->arch.local_int.wq = &vcpu->wq; vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags; - /* - * Allocate a save area for floating-point registers. If the vector - * extension is available, register contents are saved in the SIE - * control block. The allocated save area is still required in - * particular places, for example, in kvm_s390_vcpu_store_status(). - */ - vcpu->arch.guest_fpregs.fprs = kzalloc(sizeof(freg_t) * __NUM_FPRS, - GFP_KERNEL); - if (!vcpu->arch.guest_fpregs.fprs) - goto out_free_sie_block; - rc = kvm_vcpu_init(vcpu, kvm, id); if (rc) goto out_free_sie_block; @@ -1879,19 +1837,27 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { + /* make sure the new values will be lazily loaded */ + save_fpu_regs(); if (test_fp_ctl(fpu->fpc)) return -EINVAL; - memcpy(vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs)); - vcpu->arch.guest_fpregs.fpc = fpu->fpc; - save_fpu_regs(); - load_fpu_from(&vcpu->arch.guest_fpregs); + current->thread.fpu.fpc = fpu->fpc; + if (MACHINE_HAS_VX) + convert_fp_to_vx(current->thread.fpu.vxrs, (freg_t *)fpu->fprs); + else + memcpy(current->thread.fpu.fprs, &fpu->fprs, sizeof(fpu->fprs)); return 0; } int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - memcpy(&fpu->fprs, vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs)); - fpu->fpc = vcpu->arch.guest_fpregs.fpc; + /* make sure we have the latest values */ + save_fpu_regs(); + if (MACHINE_HAS_VX) + convert_vx_to_fp((freg_t *)fpu->fprs, current->thread.fpu.vxrs); + else + memcpy(fpu->fprs, current->thread.fpu.fprs, sizeof(fpu->fprs)); + fpu->fpc = current->thread.fpu.fpc; return 0; } @@ -2396,6 +2362,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) { unsigned char archmode = 1; + freg_t fprs[NUM_FPRS]; unsigned int px; u64 clkcomp; int rc; @@ -2411,8 +2378,16 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) gpa = px; } else gpa -= __LC_FPREGS_SAVE_AREA; - rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, - vcpu->arch.guest_fpregs.fprs, 128); + + /* manually convert vector registers if necessary */ + if (MACHINE_HAS_VX) { + convert_vx_to_fp(fprs, current->thread.fpu.vxrs); + rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, + fprs, 128); + } else { + rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, + vcpu->run->s.regs.vrs, 128); + } rc |= write_guest_abs(vcpu, gpa + __LC_GPREGS_SAVE_AREA, vcpu->run->s.regs.gprs, 128); rc |= write_guest_abs(vcpu, gpa + __LC_PSW_SAVE_AREA, @@ -2420,7 +2395,7 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) rc |= write_guest_abs(vcpu, gpa + __LC_PREFIX_SAVE_AREA, &px, 4); rc |= write_guest_abs(vcpu, gpa + __LC_FP_CREG_SAVE_AREA, - &vcpu->arch.guest_fpregs.fpc, 4); + &vcpu->run->s.regs.fpc, 4); rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA, &vcpu->arch.sie_block->todpr, 4); rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA, @@ -2443,19 +2418,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) * it into the save area */ save_fpu_regs(); - if (test_kvm_facility(vcpu->kvm, 129)) { - /* - * If the vector extension is available, the vector registers - * which overlaps with floating-point registers are saved in - * the SIE-control block. Hence, extract the floating-point - * registers and the FPC value and store them in the - * guest_fpregs structure. - */ - vcpu->arch.guest_fpregs.fpc = current->thread.fpu.fpc; - convert_vx_to_fp(vcpu->arch.guest_fpregs.fprs, - current->thread.fpu.vxrs); - } else - save_fpu_to(&vcpu->arch.guest_fpregs); + vcpu->run->s.regs.fpc = current->thread.fpu.fpc; save_access_regs(vcpu->run->s.regs.acrs); return kvm_s390_store_status_unloaded(vcpu, addr); diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 1b903f6ad54a..791a4146052c 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -228,7 +228,7 @@ static inline void report_user_fault(struct pt_regs *regs, long signr) return; printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d ", regs->int_code & 0xffff, regs->int_code >> 17); - print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); + print_vma_addr(KERN_CONT "in ", regs->psw.addr); printk(KERN_CONT "\n"); printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n", regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long); @@ -256,9 +256,9 @@ static noinline void do_no_context(struct pt_regs *regs) const struct exception_table_entry *fixup; /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); + fixup = search_exception_tables(regs->psw.addr); if (fixup) { - regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE; + regs->psw.addr = extable_fixup(fixup); return; } diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index c722400c7697..73e290337092 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -98,7 +98,7 @@ void __init paging_init(void) __ctl_load(S390_lowcore.kernel_asce, 1, 1); __ctl_load(S390_lowcore.kernel_asce, 7, 7); __ctl_load(S390_lowcore.kernel_asce, 13, 13); - arch_local_irq_restore(4UL << (BITS_PER_LONG - 8)); + __arch_local_irq_stosm(0x04); sparse_memory_present_with_active_regions(MAX_NUMNODES); sparse_init(); diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index ea01477b4aa6..45c4daa49930 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -169,12 +169,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) { - if (is_compat_task() || (TASK_SIZE >= (1UL << 53))) + if (is_compat_task() || TASK_SIZE >= TASK_MAX_SIZE) return 0; if (!(flags & MAP_FIXED)) addr = 0; if ((addr + len) >= TASK_SIZE) - return crst_table_upgrade(current->mm, 1UL << 53); + return crst_table_upgrade(current->mm, TASK_MAX_SIZE); return 0; } @@ -189,9 +189,9 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); if (!(area & ~PAGE_MASK)) return area; - if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) { + if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { /* Upgrade the page table to 4 levels and retry. */ - rc = crst_table_upgrade(mm, 1UL << 53); + rc = crst_table_upgrade(mm, TASK_MAX_SIZE); if (rc) return (unsigned long) rc; area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); @@ -211,9 +211,9 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); if (!(area & ~PAGE_MASK)) return area; - if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) { + if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { /* Upgrade the page table to 4 levels and retry. */ - rc = crst_table_upgrade(mm, 1UL << 53); + rc = crst_table_upgrade(mm, TASK_MAX_SIZE); if (rc) return (unsigned long) rc; area = arch_get_unmapped_area_topdown(filp, addr, len, diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index a809fa8e6f8b..5109827883ac 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -55,7 +55,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long limit) unsigned long entry; int flush; - BUG_ON(limit > (1UL << 53)); + BUG_ON(limit > TASK_MAX_SIZE); flush = 0; repeat: table = crst_table_alloc(mm); diff --git a/arch/s390/numa/numa.c b/arch/s390/numa/numa.c index 43f32ce60aa3..2794845061c6 100644 --- a/arch/s390/numa/numa.c +++ b/arch/s390/numa/numa.c @@ -57,9 +57,7 @@ static __init pg_data_t *alloc_node_data(void) { pg_data_t *res; - res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 1); - if (!res) - panic("Could not allocate memory for node data!\n"); + res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 8); memset(res, 0, sizeof(pg_data_t)); return res; } @@ -162,7 +160,7 @@ static int __init numa_init_late(void) register_one_node(nid); return 0; } -device_initcall(numa_init_late); +arch_initcall(numa_init_late); static int __init parse_debug(char *parm) { diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c index 8a6811b2cdb9..fe0bfe370c45 100644 --- a/arch/s390/oprofile/backtrace.c +++ b/arch/s390/oprofile/backtrace.c @@ -16,24 +16,23 @@ __show_trace(unsigned int *depth, unsigned long sp, struct pt_regs *regs; while (*depth) { - sp = sp & PSW_ADDR_INSN; if (sp < low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; (*depth)--; - oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN); + oprofile_add_trace(sf->gprs[8]); /* Follow the backchain. */ while (*depth) { low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; + sp = sf->back_chain; if (!sp) break; if (sp <= low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; (*depth)--; - oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN); + oprofile_add_trace(sf->gprs[8]); } @@ -46,7 +45,7 @@ __show_trace(unsigned int *depth, unsigned long sp, return sp; regs = (struct pt_regs *) sp; (*depth)--; - oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN); + oprofile_add_trace(sf->gprs[8]); low = sp; sp = regs->gprs[15]; } diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 11d4f277e9f6..8f19c8f9d660 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -68,9 +68,12 @@ static struct airq_struct zpci_airq = { .isc = PCI_ISC, }; -/* I/O Map */ +#define ZPCI_IOMAP_ENTRIES \ + min(((unsigned long) CONFIG_PCI_NR_FUNCTIONS * PCI_BAR_COUNT), \ + ZPCI_IOMAP_MAX_ENTRIES) + static DEFINE_SPINLOCK(zpci_iomap_lock); -static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); +static unsigned long *zpci_iomap_bitmap; struct zpci_iomap_entry *zpci_iomap_start; EXPORT_SYMBOL_GPL(zpci_iomap_start); @@ -265,27 +268,20 @@ void __iomem *pci_iomap_range(struct pci_dev *pdev, unsigned long max) { struct zpci_dev *zdev = to_zpci(pdev); - u64 addr; int idx; - if ((bar & 7) != bar) + if (!pci_resource_len(pdev, bar)) return NULL; idx = zdev->bars[bar].map_idx; spin_lock(&zpci_iomap_lock); - if (zpci_iomap_start[idx].count++) { - BUG_ON(zpci_iomap_start[idx].fh != zdev->fh || - zpci_iomap_start[idx].bar != bar); - } else { - zpci_iomap_start[idx].fh = zdev->fh; - zpci_iomap_start[idx].bar = bar; - } /* Detect overrun */ - BUG_ON(!zpci_iomap_start[idx].count); + WARN_ON(!++zpci_iomap_start[idx].count); + zpci_iomap_start[idx].fh = zdev->fh; + zpci_iomap_start[idx].bar = bar; spin_unlock(&zpci_iomap_lock); - addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); - return (void __iomem *) addr + offset; + return (void __iomem *) ZPCI_ADDR(idx) + offset; } EXPORT_SYMBOL(pci_iomap_range); @@ -297,12 +293,11 @@ EXPORT_SYMBOL(pci_iomap); void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) { - unsigned int idx; + unsigned int idx = ZPCI_IDX(addr); - idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48; spin_lock(&zpci_iomap_lock); /* Detect underrun */ - BUG_ON(!zpci_iomap_start[idx].count); + WARN_ON(!zpci_iomap_start[idx].count); if (!--zpci_iomap_start[idx].count) { zpci_iomap_start[idx].fh = 0; zpci_iomap_start[idx].bar = 0; @@ -544,15 +539,15 @@ static void zpci_irq_exit(void) static int zpci_alloc_iomap(struct zpci_dev *zdev) { - int entry; + unsigned long entry; spin_lock(&zpci_iomap_lock); - entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); - if (entry == ZPCI_IOMAP_MAX_ENTRIES) { + entry = find_first_zero_bit(zpci_iomap_bitmap, ZPCI_IOMAP_ENTRIES); + if (entry == ZPCI_IOMAP_ENTRIES) { spin_unlock(&zpci_iomap_lock); return -ENOSPC; } - set_bit(entry, zpci_iomap); + set_bit(entry, zpci_iomap_bitmap); spin_unlock(&zpci_iomap_lock); return entry; } @@ -561,7 +556,7 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) { spin_lock(&zpci_iomap_lock); memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry)); - clear_bit(entry, zpci_iomap); + clear_bit(entry, zpci_iomap_bitmap); spin_unlock(&zpci_iomap_lock); } @@ -611,8 +606,7 @@ static int zpci_setup_bus_resources(struct zpci_dev *zdev, if (zdev->bars[i].val & 4) flags |= IORESOURCE_MEM_64; - addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); - + addr = ZPCI_ADDR(entry); size = 1UL << zdev->bars[i].size; res = __alloc_res(zdev, addr, size, flags); @@ -873,23 +867,30 @@ static int zpci_mem_init(void) zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb), 16, 0, NULL); if (!zdev_fmb_cache) - goto error_zdev; + goto error_fmb; - /* TODO: use realloc */ - zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), - GFP_KERNEL); + zpci_iomap_start = kcalloc(ZPCI_IOMAP_ENTRIES, + sizeof(*zpci_iomap_start), GFP_KERNEL); if (!zpci_iomap_start) goto error_iomap; - return 0; + zpci_iomap_bitmap = kcalloc(BITS_TO_LONGS(ZPCI_IOMAP_ENTRIES), + sizeof(*zpci_iomap_bitmap), GFP_KERNEL); + if (!zpci_iomap_bitmap) + goto error_iomap_bitmap; + + return 0; +error_iomap_bitmap: + kfree(zpci_iomap_start); error_iomap: kmem_cache_destroy(zdev_fmb_cache); -error_zdev: +error_fmb: return -ENOMEM; } static void zpci_mem_exit(void) { + kfree(zpci_iomap_bitmap); kfree(zpci_iomap_start); kmem_cache_destroy(zdev_fmb_cache); } diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index 369a3e05d468..b0e04751c5d5 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c @@ -53,6 +53,11 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf) pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n", pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid); + + if (!pdev) + return; + + pdev->error_state = pci_channel_io_perm_failure; } void zpci_event_error(void *data) diff --git a/arch/sh/include/asm/barrier.h b/arch/sh/include/asm/barrier.h index f887c6465a82..8a84e05adb2e 100644 --- a/arch/sh/include/asm/barrier.h +++ b/arch/sh/include/asm/barrier.h @@ -33,7 +33,6 @@ #endif #define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0) -#define smp_store_mb(var, value) __smp_store_mb(var, value) #include <asm-generic/barrier.h> diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index e13d41c392ae..f878bec23576 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -34,21 +34,18 @@ struct page; #if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT) -typedef struct { unsigned long pte_low, pte_high; } pte_t; +typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; -#define pte_val(x) ((x).pte_low | ((unsigned long long) (x).pte_high << 32)) - -#define pte_get_bits(pte, bits) ((pte).pte_low & (bits)) -#define pte_set_bits(pte, bits) ((pte).pte_low |= (bits)) -#define pte_clear_bits(pte, bits) ((pte).pte_low &= ~(bits)) -#define pte_copy(to, from) ({ (to).pte_high = (from).pte_high; \ - smp_wmb(); \ - (to).pte_low = (from).pte_low; }) -#define pte_is_zero(pte) (!((pte).pte_low & ~_PAGE_NEWPAGE) && !(pte).pte_high) -#define pte_set_val(pte, phys, prot) \ - ({ (pte).pte_high = (phys) >> 32; \ - (pte).pte_low = (phys) | pgprot_val(prot); }) +#define pte_val(p) ((p).pte) + +#define pte_get_bits(p, bits) ((p).pte & (bits)) +#define pte_set_bits(p, bits) ((p).pte |= (bits)) +#define pte_clear_bits(p, bits) ((p).pte &= ~(bits)) +#define pte_copy(to, from) ({ (to).pte = (from).pte; }) +#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE)) +#define pte_set_val(p, phys, prot) \ + ({ (p).pte = (phys) | pgprot_val(prot); }) #define pmd_val(x) ((x).pmd) #define __pmd(x) ((pmd_t) { (x) } ) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 330e738ccfc1..9af2e6338400 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -509,11 +509,10 @@ config X86_INTEL_CE config X86_INTEL_MID bool "Intel MID platform support" - depends on X86_32 depends on X86_EXTENDED_PLATFORM depends on X86_PLATFORM_DEVICES depends on PCI - depends on PCI_GOANY + depends on X86_64 || (PCI_GOANY && X86_32) depends on X86_IO_APIC select SFI select I2C diff --git a/arch/x86/crypto/chacha20-ssse3-x86_64.S b/arch/x86/crypto/chacha20-ssse3-x86_64.S index 712b13047b41..3a33124e9112 100644 --- a/arch/x86/crypto/chacha20-ssse3-x86_64.S +++ b/arch/x86/crypto/chacha20-ssse3-x86_64.S @@ -157,7 +157,9 @@ ENTRY(chacha20_4block_xor_ssse3) # done with the slightly better performing SSSE3 byte shuffling, # 7/12-bit word rotation uses traditional shift+OR. - sub $0x40,%rsp + mov %rsp,%r11 + sub $0x80,%rsp + and $~63,%rsp # x0..15[0-3] = s0..3[0..3] movq 0x00(%rdi),%xmm1 @@ -620,6 +622,6 @@ ENTRY(chacha20_4block_xor_ssse3) pxor %xmm1,%xmm15 movdqu %xmm15,0xf0(%rsi) - add $0x40,%rsp + mov %r11,%rsp ret ENDPROC(chacha20_4block_xor_ssse3) diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 881b4768644a..e7de5c9a4fbd 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -23,11 +23,13 @@ extern void irq_ctx_init(int cpu); #define __ARCH_HAS_DO_SOFTIRQ +struct irq_desc; + #ifdef CONFIG_HOTPLUG_CPU #include <linux/cpumask.h> extern int check_irq_vectors_for_cpu_disable(void); extern void fixup_irqs(void); -extern void irq_force_complete_move(int); +extern void irq_force_complete_move(struct irq_desc *desc); #endif #ifdef CONFIG_HAVE_KVM @@ -37,7 +39,6 @@ extern void kvm_set_posted_intr_wakeup_handler(void (*handler)(void)); extern void (*x86_platform_ipi_callback)(void); extern void native_init_IRQ(void); -struct irq_desc; extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs); extern __visible unsigned int do_IRQ(struct pt_regs *regs); diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 04c27a013165..4432ab7f407c 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -366,20 +366,18 @@ static inline enum page_cache_mode pgprot2cachemode(pgprot_t pgprot) } static inline pgprot_t pgprot_4k_2_large(pgprot_t pgprot) { + pgprotval_t val = pgprot_val(pgprot); pgprot_t new; - unsigned long val; - val = pgprot_val(pgprot); pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) | ((val & _PAGE_PAT) << (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT)); return new; } static inline pgprot_t pgprot_large_2_4k(pgprot_t pgprot) { + pgprotval_t val = pgprot_val(pgprot); pgprot_t new; - unsigned long val; - val = pgprot_val(pgprot); pgprot_val(new) = (val & ~(_PAGE_PAT | _PAGE_PAT_LARGE)) | ((val & _PAGE_PAT_LARGE) >> (_PAGE_BIT_PAT_LARGE - _PAGE_BIT_PAT)); diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index f25321894ad2..fdb0fbfb1197 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2521,6 +2521,7 @@ void __init setup_ioapic_dest(void) { int pin, ioapic, irq, irq_entry; const struct cpumask *mask; + struct irq_desc *desc; struct irq_data *idata; struct irq_chip *chip; @@ -2536,7 +2537,9 @@ void __init setup_ioapic_dest(void) if (irq < 0 || !mp_init_irq_at_boot(ioapic, irq)) continue; - idata = irq_get_irq_data(irq); + desc = irq_to_desc(irq); + raw_spin_lock_irq(&desc->lock); + idata = irq_desc_get_irq_data(desc); /* * Honour affinities which have been set in early boot @@ -2550,6 +2553,7 @@ void __init setup_ioapic_dest(void) /* Might be lapic_chip for irq 0 */ if (chip->irq_set_affinity) chip->irq_set_affinity(idata, mask, false); + raw_spin_unlock_irq(&desc->lock); } } #endif diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index 908cb37da171..3b670df4ba7b 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -31,7 +31,7 @@ struct apic_chip_data { struct irq_domain *x86_vector_domain; EXPORT_SYMBOL_GPL(x86_vector_domain); static DEFINE_RAW_SPINLOCK(vector_lock); -static cpumask_var_t vector_cpumask; +static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask; static struct irq_chip lapic_controller; #ifdef CONFIG_X86_IO_APIC static struct apic_chip_data *legacy_irq_data[NR_IRQS_LEGACY]; @@ -118,35 +118,47 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d, */ static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START; static int current_offset = VECTOR_OFFSET_START % 16; - int cpu, err; + int cpu, vector; - if (d->move_in_progress) + /* + * If there is still a move in progress or the previous move has not + * been cleaned up completely, tell the caller to come back later. + */ + if (d->move_in_progress || + cpumask_intersects(d->old_domain, cpu_online_mask)) return -EBUSY; /* Only try and allocate irqs on cpus that are present */ - err = -ENOSPC; cpumask_clear(d->old_domain); + cpumask_clear(searched_cpumask); cpu = cpumask_first_and(mask, cpu_online_mask); while (cpu < nr_cpu_ids) { - int new_cpu, vector, offset; + int new_cpu, offset; + /* Get the possible target cpus for @mask/@cpu from the apic */ apic->vector_allocation_domain(cpu, vector_cpumask, mask); + /* + * Clear the offline cpus from @vector_cpumask for searching + * and verify whether the result overlaps with @mask. If true, + * then the call to apic->cpu_mask_to_apicid_and() will + * succeed as well. If not, no point in trying to find a + * vector in this mask. + */ + cpumask_and(vector_searchmask, vector_cpumask, cpu_online_mask); + if (!cpumask_intersects(vector_searchmask, mask)) + goto next_cpu; + if (cpumask_subset(vector_cpumask, d->domain)) { - err = 0; if (cpumask_equal(vector_cpumask, d->domain)) - break; + goto success; /* - * New cpumask using the vector is a proper subset of - * the current in use mask. So cleanup the vector - * allocation for the members that are not used anymore. + * Mark the cpus which are not longer in the mask for + * cleanup. */ - cpumask_andnot(d->old_domain, d->domain, - vector_cpumask); - d->move_in_progress = - cpumask_intersects(d->old_domain, cpu_online_mask); - cpumask_and(d->domain, d->domain, vector_cpumask); - break; + cpumask_andnot(d->old_domain, d->domain, vector_cpumask); + vector = d->cfg.vector; + goto update; } vector = current_vector; @@ -158,45 +170,60 @@ next: vector = FIRST_EXTERNAL_VECTOR + offset; } - if (unlikely(current_vector == vector)) { - cpumask_or(d->old_domain, d->old_domain, - vector_cpumask); - cpumask_andnot(vector_cpumask, mask, d->old_domain); - cpu = cpumask_first_and(vector_cpumask, - cpu_online_mask); - continue; - } + /* If the search wrapped around, try the next cpu */ + if (unlikely(current_vector == vector)) + goto next_cpu; if (test_bit(vector, used_vectors)) goto next; - for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) { + for_each_cpu(new_cpu, vector_searchmask) { if (!IS_ERR_OR_NULL(per_cpu(vector_irq, new_cpu)[vector])) goto next; } /* Found one! */ current_vector = vector; current_offset = offset; - if (d->cfg.vector) { + /* Schedule the old vector for cleanup on all cpus */ + if (d->cfg.vector) cpumask_copy(d->old_domain, d->domain); - d->move_in_progress = - cpumask_intersects(d->old_domain, cpu_online_mask); - } - for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) + for_each_cpu(new_cpu, vector_searchmask) per_cpu(vector_irq, new_cpu)[vector] = irq_to_desc(irq); - d->cfg.vector = vector; - cpumask_copy(d->domain, vector_cpumask); - err = 0; - break; - } + goto update; - if (!err) { - /* cache destination APIC IDs into cfg->dest_apicid */ - err = apic->cpu_mask_to_apicid_and(mask, d->domain, - &d->cfg.dest_apicid); +next_cpu: + /* + * We exclude the current @vector_cpumask from the requested + * @mask and try again with the next online cpu in the + * result. We cannot modify @mask, so we use @vector_cpumask + * as a temporary buffer here as it will be reassigned when + * calling apic->vector_allocation_domain() above. + */ + cpumask_or(searched_cpumask, searched_cpumask, vector_cpumask); + cpumask_andnot(vector_cpumask, mask, searched_cpumask); + cpu = cpumask_first_and(vector_cpumask, cpu_online_mask); + continue; } + return -ENOSPC; - return err; +update: + /* + * Exclude offline cpus from the cleanup mask and set the + * move_in_progress flag when the result is not empty. + */ + cpumask_and(d->old_domain, d->old_domain, cpu_online_mask); + d->move_in_progress = !cpumask_empty(d->old_domain); + d->cfg.vector = vector; + cpumask_copy(d->domain, vector_cpumask); +success: + /* + * Cache destination APIC IDs into cfg->dest_apicid. This cannot fail + * as we already established, that mask & d->domain & cpu_online_mask + * is not empty. + */ + BUG_ON(apic->cpu_mask_to_apicid_and(mask, d->domain, + &d->cfg.dest_apicid)); + return 0; } static int assign_irq_vector(int irq, struct apic_chip_data *data, @@ -226,10 +253,8 @@ static int assign_irq_vector_policy(int irq, int node, static void clear_irq_vector(int irq, struct apic_chip_data *data) { struct irq_desc *desc; - unsigned long flags; int cpu, vector; - raw_spin_lock_irqsave(&vector_lock, flags); BUG_ON(!data->cfg.vector); vector = data->cfg.vector; @@ -239,10 +264,13 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data) data->cfg.vector = 0; cpumask_clear(data->domain); - if (likely(!data->move_in_progress)) { - raw_spin_unlock_irqrestore(&vector_lock, flags); + /* + * If move is in progress or the old_domain mask is not empty, + * i.e. the cleanup IPI has not been processed yet, we need to remove + * the old references to desc from all cpus vector tables. + */ + if (!data->move_in_progress && cpumask_empty(data->old_domain)) return; - } desc = irq_to_desc(irq); for_each_cpu_and(cpu, data->old_domain, cpu_online_mask) { @@ -255,7 +283,6 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data) } } data->move_in_progress = 0; - raw_spin_unlock_irqrestore(&vector_lock, flags); } void init_irq_alloc_info(struct irq_alloc_info *info, @@ -276,19 +303,24 @@ void copy_irq_alloc_info(struct irq_alloc_info *dst, struct irq_alloc_info *src) static void x86_vector_free_irqs(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs) { + struct apic_chip_data *apic_data; struct irq_data *irq_data; + unsigned long flags; int i; for (i = 0; i < nr_irqs; i++) { irq_data = irq_domain_get_irq_data(x86_vector_domain, virq + i); if (irq_data && irq_data->chip_data) { + raw_spin_lock_irqsave(&vector_lock, flags); clear_irq_vector(virq + i, irq_data->chip_data); - free_apic_chip_data(irq_data->chip_data); + apic_data = irq_data->chip_data; + irq_domain_reset_irq_data(irq_data); + raw_spin_unlock_irqrestore(&vector_lock, flags); + free_apic_chip_data(apic_data); #ifdef CONFIG_X86_IO_APIC if (virq + i < nr_legacy_irqs()) legacy_irq_data[virq + i] = NULL; #endif - irq_domain_reset_irq_data(irq_data); } } } @@ -406,6 +438,8 @@ int __init arch_early_irq_init(void) arch_init_htirq_domain(x86_vector_domain); BUG_ON(!alloc_cpumask_var(&vector_cpumask, GFP_KERNEL)); + BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL)); + BUG_ON(!alloc_cpumask_var(&searched_cpumask, GFP_KERNEL)); return arch_early_ioapic_init(); } @@ -494,14 +528,7 @@ static int apic_set_affinity(struct irq_data *irq_data, return -EINVAL; err = assign_irq_vector(irq, data, dest); - if (err) { - if (assign_irq_vector(irq, data, - irq_data_get_affinity_mask(irq_data))) - pr_err("Failed to recover vector for irq %d\n", irq); - return err; - } - - return IRQ_SET_MASK_OK; + return err ? err : IRQ_SET_MASK_OK; } static struct irq_chip lapic_controller = { @@ -513,20 +540,12 @@ static struct irq_chip lapic_controller = { #ifdef CONFIG_SMP static void __send_cleanup_vector(struct apic_chip_data *data) { - cpumask_var_t cleanup_mask; - - if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) { - unsigned int i; - - for_each_cpu_and(i, data->old_domain, cpu_online_mask) - apic->send_IPI_mask(cpumask_of(i), - IRQ_MOVE_CLEANUP_VECTOR); - } else { - cpumask_and(cleanup_mask, data->old_domain, cpu_online_mask); - apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); - free_cpumask_var(cleanup_mask); - } + raw_spin_lock(&vector_lock); + cpumask_and(data->old_domain, data->old_domain, cpu_online_mask); data->move_in_progress = 0; + if (!cpumask_empty(data->old_domain)) + apic->send_IPI_mask(data->old_domain, IRQ_MOVE_CLEANUP_VECTOR); + raw_spin_unlock(&vector_lock); } void send_cleanup_vector(struct irq_cfg *cfg) @@ -570,12 +589,25 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) goto unlock; /* - * Check if the irq migration is in progress. If so, we - * haven't received the cleanup request yet for this irq. + * Nothing to cleanup if irq migration is in progress + * or this cpu is not set in the cleanup mask. */ - if (data->move_in_progress) + if (data->move_in_progress || + !cpumask_test_cpu(me, data->old_domain)) goto unlock; + /* + * We have two cases to handle here: + * 1) vector is unchanged but the target mask got reduced + * 2) vector and the target mask has changed + * + * #1 is obvious, but in #2 we have two vectors with the same + * irq descriptor: the old and the new vector. So we need to + * make sure that we only cleanup the old vector. The new + * vector has the current @vector number in the config and + * this cpu is part of the target mask. We better leave that + * one alone. + */ if (vector == data->cfg.vector && cpumask_test_cpu(me, data->domain)) goto unlock; @@ -593,6 +625,7 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) goto unlock; } __this_cpu_write(vector_irq[vector], VECTOR_UNUSED); + cpumask_clear_cpu(me, data->old_domain); unlock: raw_spin_unlock(&desc->lock); } @@ -621,12 +654,48 @@ void irq_complete_move(struct irq_cfg *cfg) __irq_complete_move(cfg, ~get_irq_regs()->orig_ax); } -void irq_force_complete_move(int irq) +/* + * Called with @desc->lock held and interrupts disabled. + */ +void irq_force_complete_move(struct irq_desc *desc) { - struct irq_cfg *cfg = irq_cfg(irq); + struct irq_data *irqdata = irq_desc_get_irq_data(desc); + struct apic_chip_data *data = apic_chip_data(irqdata); + struct irq_cfg *cfg = data ? &data->cfg : NULL; - if (cfg) - __irq_complete_move(cfg, cfg->vector); + if (!cfg) + return; + + __irq_complete_move(cfg, cfg->vector); + + /* + * This is tricky. If the cleanup of @data->old_domain has not been + * done yet, then the following setaffinity call will fail with + * -EBUSY. This can leave the interrupt in a stale state. + * + * The cleanup cannot make progress because we hold @desc->lock. So in + * case @data->old_domain is not yet cleaned up, we need to drop the + * lock and acquire it again. @desc cannot go away, because the + * hotplug code holds the sparse irq lock. + */ + raw_spin_lock(&vector_lock); + /* Clean out all offline cpus (including ourself) first. */ + cpumask_and(data->old_domain, data->old_domain, cpu_online_mask); + while (!cpumask_empty(data->old_domain)) { + raw_spin_unlock(&vector_lock); + raw_spin_unlock(&desc->lock); + cpu_relax(); + raw_spin_lock(&desc->lock); + /* + * Reevaluate apic_chip_data. It might have been cleared after + * we dropped @desc->lock. + */ + data = apic_chip_data(irqdata); + if (!data) + return; + raw_spin_lock(&vector_lock); + } + raw_spin_unlock(&vector_lock); } #endif diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index d760c6bb37b5..624db00583f4 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -889,7 +889,10 @@ void __init uv_system_init(void) return; } pr_info("UV: Found %s hub\n", hub); - map_low_mmrs(); + + /* We now only need to map the MMRs on UV1 */ + if (is_uv1_hub()) + map_low_mmrs(); m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); m_val = m_n_config.s.m_skt; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index a667078a5180..fed2ab1f1065 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1960,7 +1960,8 @@ intel_bts_constraints(struct perf_event *event) static int intel_alt_er(int idx, u64 config) { - int alt_idx; + int alt_idx = idx; + if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1)) return idx; @@ -2897,14 +2898,12 @@ static void intel_pmu_cpu_starting(int cpu) return; if (!(x86_pmu.flags & PMU_FL_NO_HT_SHARING)) { - void **onln = &cpuc->kfree_on_online[X86_PERF_KFREE_SHARED]; - for_each_cpu(i, topology_sibling_cpumask(cpu)) { struct intel_shared_regs *pc; pc = per_cpu(cpu_hw_events, i).shared_regs; if (pc && pc->core_id == core_id) { - *onln = cpuc->shared_regs; + cpuc->kfree_on_online[0] = cpuc->shared_regs; cpuc->shared_regs = pc; break; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index f97f8075bf04..3bf41d413775 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -995,6 +995,9 @@ static int __init uncore_pci_init(void) case 87: /* Knights Landing */ ret = knl_uncore_pci_init(); break; + case 94: /* SkyLake */ + ret = skl_uncore_pci_init(); + break; default: return 0; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 07aa2d6bd710..a7086b862156 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -336,6 +336,7 @@ int snb_uncore_pci_init(void); int ivb_uncore_pci_init(void); int hsw_uncore_pci_init(void); int bdw_uncore_pci_init(void); +int skl_uncore_pci_init(void); void snb_uncore_cpu_init(void); void nhm_uncore_cpu_init(void); int snb_pci2phy_map_init(int devid); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c index 0b934820fafd..2bd030ddd0db 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c @@ -8,6 +8,7 @@ #define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00 #define PCI_DEVICE_ID_INTEL_HSW_U_IMC 0x0a04 #define PCI_DEVICE_ID_INTEL_BDW_IMC 0x1604 +#define PCI_DEVICE_ID_INTEL_SKL_IMC 0x191f /* SNB event control */ #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff @@ -524,6 +525,14 @@ static const struct pci_device_id bdw_uncore_pci_ids[] = { { /* end: all zeroes */ }, }; +static const struct pci_device_id skl_uncore_pci_ids[] = { + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, + { /* end: all zeroes */ }, +}; + static struct pci_driver snb_uncore_pci_driver = { .name = "snb_uncore", .id_table = snb_uncore_pci_ids, @@ -544,6 +553,11 @@ static struct pci_driver bdw_uncore_pci_driver = { .id_table = bdw_uncore_pci_ids, }; +static struct pci_driver skl_uncore_pci_driver = { + .name = "skl_uncore", + .id_table = skl_uncore_pci_ids, +}; + struct imc_uncore_pci_dev { __u32 pci_id; struct pci_driver *driver; @@ -558,6 +572,7 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = { IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */ IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */ IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver), /* 5th Gen Core U */ + IMC_DEV(SKL_IMC, &skl_uncore_pci_driver), /* 6th Gen Core */ { /* end marker */ } }; @@ -610,6 +625,11 @@ int bdw_uncore_pci_init(void) return imc_uncore_pci_init(); } +int skl_uncore_pci_init(void) +{ + return imc_uncore_pci_init(); +} + /* end of Sandy Bridge uncore support */ /* Nehalem uncore support */ diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index f129a9af6357..2c0f3407bd1f 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -192,5 +192,13 @@ void __init x86_64_start_reservations(char *real_mode_data) reserve_ebda_region(); + switch (boot_params.hdr.hardware_subarch) { + case X86_SUBARCH_INTEL_MID: + x86_intel_mid_early_setup(); + break; + default: + break; + } + start_kernel(); } diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index f8062aaf5df9..61521dc19c10 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -462,7 +462,7 @@ void fixup_irqs(void) * non intr-remapping case, we can't wait till this interrupt * arrives at this cpu before completing the irq move. */ - irq_force_complete_move(irq); + irq_force_complete_move(desc); if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { break_affinity = 1; @@ -470,6 +470,15 @@ void fixup_irqs(void) } chip = irq_data_get_irq_chip(data); + /* + * The interrupt descriptor might have been cleaned up + * already, but it is not yet removed from the radix tree + */ + if (!chip) { + raw_spin_unlock(&desc->lock); + continue; + } + if (!irqd_can_move_in_process_context(data) && chip->irq_mask) chip->irq_mask(data); diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c index 42982b26e32b..740d7ac03a55 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c @@ -173,10 +173,10 @@ static __init int setup_hugepagesz(char *opt) } __setup("hugepagesz=", setup_hugepagesz); -#ifdef CONFIG_CMA +#if (defined(CONFIG_MEMORY_ISOLATION) && defined(CONFIG_COMPACTION)) || defined(CONFIG_CMA) static __init int gigantic_pages_init(void) { - /* With CMA we can allocate gigantic pages at runtime */ + /* With compaction or CMA we can allocate gigantic pages at runtime */ if (cpu_has_gbpages && !size_to_hstate(1UL << PUD_SHIFT)) hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); return 0; diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index fc6a4c8f6e2a..2440814b0069 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -33,7 +33,7 @@ struct cpa_data { pgd_t *pgd; pgprot_t mask_set; pgprot_t mask_clr; - int numpages; + unsigned long numpages; int flags; unsigned long pfn; unsigned force_split : 1; @@ -1350,7 +1350,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) * CPA operation. Either a large page has been * preserved or a single page update happened. */ - BUG_ON(cpa->numpages > numpages); + BUG_ON(cpa->numpages > numpages || !cpa->numpages); numpages -= cpa->numpages; if (cpa->flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) cpa->curpage++; diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 1c7380da65ff..2d66db8f80f9 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -8,6 +8,7 @@ #include <linux/memblock.h> #include <linux/bootmem.h> #include <linux/acpi.h> +#include <linux/dmi.h> #include <asm/efi.h> #include <asm/uv/uv.h> @@ -248,6 +249,16 @@ out: return ret; } +static const struct dmi_system_id sgi_uv1_dmi[] = { + { NULL, "SGI UV1", + { DMI_MATCH(DMI_PRODUCT_NAME, "Stoutland Platform"), + DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), + DMI_MATCH(DMI_BIOS_VENDOR, "SGI.COM"), + } + }, + { } /* NULL entry stops DMI scanning */ +}; + void __init efi_apply_memmap_quirks(void) { /* @@ -260,10 +271,8 @@ void __init efi_apply_memmap_quirks(void) efi_unmap_memmap(); } - /* - * UV doesn't support the new EFI pagetable mapping yet. - */ - if (is_uv_system()) + /* UV2+ BIOS has a fix for this issue. UV1 still needs the quirk. */ + if (dmi_check_system(sgi_uv1_dmi)) set_bit(EFI_OLD_MEMMAP, &efi.flags); } diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c index 1bbc21e2e4ae..90bb997ed0a2 100644 --- a/arch/x86/platform/intel-mid/intel-mid.c +++ b/arch/x86/platform/intel-mid/intel-mid.c @@ -138,7 +138,7 @@ static void intel_mid_arch_setup(void) intel_mid_ops = get_intel_mid_ops[__intel_mid_cpu_chip](); else { intel_mid_ops = get_intel_mid_ops[INTEL_MID_CPU_CHIP_PENWELL](); - pr_info("ARCH: Unknown SoC, assuming PENWELL!\n"); + pr_info("ARCH: Unknown SoC, assuming Penwell!\n"); } out: @@ -214,12 +214,10 @@ static inline int __init setup_x86_intel_mid_timer(char *arg) else if (strcmp("lapic_and_apbt", arg) == 0) intel_mid_timer_options = INTEL_MID_TIMER_LAPIC_APBT; else { - pr_warn("X86 INTEL_MID timer option %s not recognised" - " use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n", - arg); + pr_warn("X86 INTEL_MID timer option %s not recognised use x86_intel_mid_timer=apbt_only or lapic_and_apbt\n", + arg); return -EINVAL; } return 0; } __setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer); - diff --git a/arch/x86/platform/intel-quark/imr.c b/arch/x86/platform/intel-quark/imr.c index c1bdafaac3ca..c61b6c332e97 100644 --- a/arch/x86/platform/intel-quark/imr.c +++ b/arch/x86/platform/intel-quark/imr.c @@ -220,11 +220,12 @@ static int imr_dbgfs_state_show(struct seq_file *s, void *unused) if (imr_is_enabled(&imr)) { base = imr_to_phys(imr.addr_lo); end = imr_to_phys(imr.addr_hi) + IMR_MASK; + size = end - base + 1; } else { base = 0; end = 0; + size = 0; } - size = end - base; seq_printf(s, "imr%02i: base=%pa, end=%pa, size=0x%08zx " "rmask=0x%08x, wmask=0x%08x, %s, %s\n", i, &base, &end, size, imr.rmask, imr.wmask, @@ -579,6 +580,7 @@ static void __init imr_fixup_memmap(struct imr_device *idev) { phys_addr_t base = virt_to_phys(&_text); size_t size = virt_to_phys(&__end_rodata) - base; + unsigned long start, end; int i; int ret; @@ -586,18 +588,24 @@ static void __init imr_fixup_memmap(struct imr_device *idev) for (i = 0; i < idev->max_imr; i++) imr_clear(i); + start = (unsigned long)_text; + end = (unsigned long)__end_rodata - 1; + /* * Setup a locked IMR around the physical extent of the kernel * from the beginning of the .text secton to the end of the * .rodata section as one physically contiguous block. + * + * We don't round up @size since it is already PAGE_SIZE aligned. + * See vmlinux.lds.S for details. */ ret = imr_add_range(base, size, IMR_CPU, IMR_CPU, true); if (ret < 0) { - pr_err("unable to setup IMR for kernel: (%p - %p)\n", - &_text, &__end_rodata); + pr_err("unable to setup IMR for kernel: %zu KiB (%lx - %lx)\n", + size / 1024, start, end); } else { - pr_info("protecting kernel .text - .rodata: %zu KiB (%p - %p)\n", - size / 1024, &_text, &__end_rodata); + pr_info("protecting kernel .text - .rodata: %zu KiB (%lx - %lx)\n", + size / 1024, start, end); } } |