diff options
Diffstat (limited to 'arch/arm')
87 files changed, 1329 insertions, 1098 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e25419817791..d57b4753585d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -388,8 +388,6 @@ config ARCH_CLPS711X select CPU_ARM720T select GENERIC_CLOCKEVENTS select MFD_SYSCON - select MULTI_IRQ_HANDLER - select SPARSE_IRQ help Support for Cirrus Logic 711x/721x/731x based boards. @@ -657,9 +655,8 @@ config ARCH_PXA help Support for Intel/Marvell's PXA2xx/PXA3xx processor line. -config ARCH_MSM_NODT - bool "Qualcomm MSM" - select ARCH_MSM +config ARCH_MSM + bool "Qualcomm MSM (non-multiplatform)" select ARCH_REQUIRE_GPIOLIB select COMMON_CLK select GENERIC_CLOCKEVENTS @@ -1005,6 +1002,8 @@ source "arch/arm/plat-pxa/Kconfig" source "arch/arm/mach-mmp/Kconfig" +source "arch/arm/mach-qcom/Kconfig" + source "arch/arm/mach-realview/Kconfig" source "arch/arm/mach-rockchip/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 0531da8e5216..4491c7b05275 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -956,7 +956,7 @@ config DEBUG_STI_UART config DEBUG_MSM_UART bool - depends on ARCH_MSM + depends on ARCH_MSM || ARCH_QCOM config DEBUG_LL_INCLUDE string diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 08a9ef58d9c3..51e5bede657f 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -180,6 +180,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2 machine-$(CONFIG_ARCH_ORION5X) += orion5x machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell machine-$(CONFIG_ARCH_PXA) += pxa +machine-$(CONFIG_ARCH_QCOM) += qcom machine-$(CONFIG_ARCH_REALVIEW) += realview machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip machine-$(CONFIG_ARCH_RPC) += rpc diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b9d6a8b485e0..3269029a1ce6 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb # sama5d3 +dtb-$(CONFIG_ARCH_AT91) += at91-sama5d3_xplained.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d31ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb @@ -118,9 +119,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \ kirkwood-ts219-6282.dtb dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb -dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \ - qcom-msm8960-cdp.dtb \ - qcom-apq8074-dragonboard.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ armada-370-mirabox.dtb \ armada-370-netgear-rn102.dtb \ @@ -232,6 +230,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ dra7-evm.dtb dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \ + qcom-msm8960-cdp.dtb \ + qcom-apq8074-dragonboard.dtb dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ ste-hrefprev60-stuib.dtb \ ste-hrefprev60-tvk.dtb \ diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts new file mode 100644 index 000000000000..ce1375595e5f --- /dev/null +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts @@ -0,0 +1,229 @@ +/* + * at91-sama5d3_xplained.dts - Device Tree file for the SAMA5D3 Xplained board + * + * Copyright (C) 2014 Atmel, + * 2014 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" + +/ { + model = "SAMA5D3 Xplained"; + compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x20000000 0x10000000>; + }; + + ahb { + apb { + mmc0: mmc@f0000000 { + pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <8>; + cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>; + }; + }; + + spi0: spi@f0004000 { + cs-gpios = <&pioD 13 0>; + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + phy-mode = "rgmii"; + status = "okay"; + }; + + usart0: serial@f001c000 { + status = "okay"; + }; + + usart1: serial@f0020000 { + pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>; + status = "okay"; + }; + + uart0: serial@f0024000 { + status = "okay"; + }; + + mmc1: mmc@f8000000 { + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>; + }; + }; + + spi1: spi@f8008000 { + cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>; + status = "okay"; + }; + + adc0: adc@f8018000 { + pinctrl-0 = < + &pinctrl_adc0_adtrg + &pinctrl_adc0_ad0 + &pinctrl_adc0_ad1 + &pinctrl_adc0_ad2 + &pinctrl_adc0_ad3 + &pinctrl_adc0_ad4 + &pinctrl_adc0_ad5 + &pinctrl_adc0_ad6 + &pinctrl_adc0_ad7 + &pinctrl_adc0_ad8 + &pinctrl_adc0_ad9 + >; + status = "okay"; + }; + + i2c2: i2c@f801c000 { + dmas = <0>, <0>; /* Do not use DMA for i2c2 */ + status = "okay"; + }; + + macb1: ethernet@f802c000 { + phy-mode = "rmii"; + status = "okay"; + }; + + dbgu: serial@ffffee00 { + status = "okay"; + }; + + pinctrl@fffff200 { + board { + pinctrl_mmc0_cd: mmc0_cd { + atmel,pins = + <AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_mmc1_cd: mmc1_cd { + atmel,pins = + <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; + }; + + pinctrl_usba_vbus: usba_vbus { + atmel,pins = + <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */ + }; + }; + }; + + pmc: pmc@fffffc00 { + main: mainck { + clock-frequency = <12000000>; + }; + }; + }; + + nand0: nand@60000000 { + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + atmel,has-pmecc; + atmel,pmecc-cap = <4>; + atmel,pmecc-sector-size = <512>; + nand-on-flash-bbt; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + bootloader@40000 { + label = "bootloader"; + reg = <0x40000 0x80000>; + }; + + bootloaderenv@c0000 { + label = "bootloader env"; + reg = <0xc0000 0xc0000>; + }; + + dtb@180000 { + label = "device tree"; + reg = <0x180000 0x80000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + + usb0: gadget@00500000 { + atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00600000 { + num-ports = <3>; + atmel,vbus-gpio = <0 + &pioE 3 GPIO_ACTIVE_LOW + &pioE 4 GPIO_ACTIVE_LOW + >; + status = "okay"; + }; + + usb2: ehci@00700000 { + status = "okay"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + bp3 { + label = "PB_USER"; + gpios = <&pioE 29 GPIO_ACTIVE_LOW>; + linux,code = <0x104>; + gpio-key,wakeup; + }; + }; + + leds { + compatible = "gpio-leds"; + + d2 { + label = "d2"; + gpios = <&pioE 23 GPIO_ACTIVE_LOW>; /* PE23, conflicts with A23, CTS2 */ + linux,default-trigger = "heartbeat"; + }; + + d3 { + label = "d3"; + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 0042f73068b0..fece8665fb63 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -523,7 +523,7 @@ }; i2c0: i2c@fff88000 { - compatible = "atmel,at91sam9263-i2c"; + compatible = "atmel,at91sam9260-i2c"; reg = <0xfff88000 0x100>; interrupts = <13 IRQ_TYPE_LEVEL_HIGH 6>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index e9487f6f0166..924a6a6ffd0f 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -124,6 +124,10 @@ nand-on-flash-bbt; status = "okay"; }; + + usb0: ohci@00500000 { + status = "okay"; + }; }; leds { diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts index 68a72f5507b9..169bad90dac9 100644 --- a/arch/arm/boot/dts/qcom-msm8660-surf.dts +++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts @@ -1,63 +1,6 @@ -/dts-v1/; - -/include/ "skeleton.dtsi" - -#include <dt-bindings/clock/qcom,gcc-msm8660.h> +#include "qcom-msm8660.dtsi" / { model = "Qualcomm MSM8660 SURF"; compatible = "qcom,msm8660-surf", "qcom,msm8660"; - interrupt-parent = <&intc>; - - intc: interrupt-controller@2080000 { - compatible = "qcom,msm-8660-qgic"; - interrupt-controller; - #interrupt-cells = <3>; - reg = < 0x02080000 0x1000 >, - < 0x02081000 0x1000 >; - }; - - timer@2000000 { - compatible = "qcom,scss-timer", "qcom,msm-timer"; - interrupts = <1 0 0x301>, - <1 1 0x301>, - <1 2 0x301>; - reg = <0x02000000 0x100>; - clock-frequency = <27000000>, - <32768>; - cpu-offset = <0x40000>; - }; - - msmgpio: gpio@800000 { - compatible = "qcom,msm-gpio"; - reg = <0x00800000 0x4000>; - gpio-controller; - #gpio-cells = <2>; - ngpio = <173>; - interrupts = <0 16 0x4>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - gcc: clock-controller@900000 { - compatible = "qcom,gcc-msm8660"; - #clock-cells = <1>; - #reset-cells = <1>; - reg = <0x900000 0x4000>; - }; - - serial@19c40000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x19c40000 0x1000>, - <0x19c00000 0x1000>; - interrupts = <0 195 0x0>; - clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>; - clock-names = "core", "iface"; - }; - - qcom,ssbi@500000 { - compatible = "qcom,ssbi"; - reg = <0x500000 0x1000>; - qcom,controller-type = "pmic-arbiter"; - }; }; diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi new file mode 100644 index 000000000000..69d6c4edea30 --- /dev/null +++ b/arch/arm/boot/dts/qcom-msm8660.dtsi @@ -0,0 +1,63 @@ +/dts-v1/; + +/include/ "skeleton.dtsi" + +#include <dt-bindings/clock/qcom,gcc-msm8660.h> + +/ { + model = "Qualcomm MSM8660"; + compatible = "qcom,msm8660"; + interrupt-parent = <&intc>; + + intc: interrupt-controller@2080000 { + compatible = "qcom,msm-8660-qgic"; + interrupt-controller; + #interrupt-cells = <3>; + reg = < 0x02080000 0x1000 >, + < 0x02081000 0x1000 >; + }; + + timer@2000000 { + compatible = "qcom,scss-timer", "qcom,msm-timer"; + interrupts = <1 0 0x301>, + <1 1 0x301>, + <1 2 0x301>; + reg = <0x02000000 0x100>; + clock-frequency = <27000000>, + <32768>; + cpu-offset = <0x40000>; + }; + + msmgpio: gpio@800000 { + compatible = "qcom,msm-gpio"; + reg = <0x00800000 0x4000>; + gpio-controller; + #gpio-cells = <2>; + ngpio = <173>; + interrupts = <0 16 0x4>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gcc: clock-controller@900000 { + compatible = "qcom,gcc-msm8660"; + #clock-cells = <1>; + #reset-cells = <1>; + reg = <0x900000 0x4000>; + }; + + serial@19c40000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x19c40000 0x1000>, + <0x19c00000 0x1000>; + interrupts = <0 195 0x0>; + clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>; + clock-names = "core", "iface"; + }; + + qcom,ssbi@500000 { + compatible = "qcom,ssbi"; + reg = <0x500000 0x1000>; + qcom,controller-type = "pmic-arbiter"; + }; +}; diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts index 7c30de4fa302..a58fb88315f6 100644 --- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts +++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts @@ -1,70 +1,6 @@ -/dts-v1/; - -/include/ "skeleton.dtsi" - -#include <dt-bindings/clock/qcom,gcc-msm8960.h> +#include "qcom-msm8960.dtsi" / { model = "Qualcomm MSM8960 CDP"; compatible = "qcom,msm8960-cdp", "qcom,msm8960"; - interrupt-parent = <&intc>; - - intc: interrupt-controller@2000000 { - compatible = "qcom,msm-qgic2"; - interrupt-controller; - #interrupt-cells = <3>; - reg = < 0x02000000 0x1000 >, - < 0x02002000 0x1000 >; - }; - - timer@200a000 { - compatible = "qcom,kpss-timer", "qcom,msm-timer"; - interrupts = <1 1 0x301>, - <1 2 0x301>, - <1 3 0x301>; - reg = <0x0200a000 0x100>; - clock-frequency = <27000000>, - <32768>; - cpu-offset = <0x80000>; - }; - - msmgpio: gpio@800000 { - compatible = "qcom,msm-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpio = <150>; - interrupts = <0 16 0x4>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x800000 0x4000>; - }; - - gcc: clock-controller@900000 { - compatible = "qcom,gcc-msm8960"; - #clock-cells = <1>; - #reset-cells = <1>; - reg = <0x900000 0x4000>; - }; - - clock-controller@4000000 { - compatible = "qcom,mmcc-msm8960"; - reg = <0x4000000 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - serial@16440000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x16440000 0x1000>, - <0x16400000 0x1000>; - interrupts = <0 154 0x0>; - clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>; - clock-names = "core", "iface"; - }; - - qcom,ssbi@500000 { - compatible = "qcom,ssbi"; - reg = <0x500000 0x1000>; - qcom,controller-type = "pmic-arbiter"; - }; }; diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi new file mode 100644 index 000000000000..3a9c3caa9aad --- /dev/null +++ b/arch/arm/boot/dts/qcom-msm8960.dtsi @@ -0,0 +1,76 @@ +/dts-v1/; + +/include/ "skeleton.dtsi" + +#include <dt-bindings/clock/qcom,gcc-msm8960.h> + +/ { + model = "Qualcomm MSM8960"; + compatible = "qcom,msm8960"; + interrupt-parent = <&intc>; + + cpu-pmu { + compatible = "qcom,krait-pmu"; + interrupts = <1 10 0x304>; + qcom,no-pc-write; + }; + + intc: interrupt-controller@2000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <3>; + reg = < 0x02000000 0x1000 >, + < 0x02002000 0x1000 >; + }; + + timer@200a000 { + compatible = "qcom,kpss-timer", "qcom,msm-timer"; + interrupts = <1 1 0x301>, + <1 2 0x301>, + <1 3 0x301>; + reg = <0x0200a000 0x100>; + clock-frequency = <27000000>, + <32768>; + cpu-offset = <0x80000>; + }; + + msmgpio: gpio@800000 { + compatible = "qcom,msm-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpio = <150>; + interrupts = <0 16 0x4>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x800000 0x4000>; + }; + + gcc: clock-controller@900000 { + compatible = "qcom,gcc-msm8960"; + #clock-cells = <1>; + #reset-cells = <1>; + reg = <0x900000 0x4000>; + }; + + clock-controller@4000000 { + compatible = "qcom,mmcc-msm8960"; + reg = <0x4000000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + serial@16440000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x16440000 0x1000>, + <0x16400000 0x1000>; + interrupts = <0 154 0x0>; + clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>; + clock-names = "core", "iface"; + }; + + qcom,ssbi@500000 { + compatible = "qcom,ssbi"; + reg = <0x500000 0x1000>; + qcom,controller-type = "pmic-arbiter"; + }; +}; diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 9e5dadb101eb..1eff4130cde0 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -9,6 +9,11 @@ compatible = "qcom,msm8974"; interrupt-parent = <&intc>; + cpu-pmu { + compatible = "qcom,krait-pmu"; + interrupts = <1 7 0xf04>; + }; + soc: soc { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index be5d2b09a363..4d4dfbb59f4b 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -64,6 +64,19 @@ clock-names = "timer", "pclk"; }; + sram: sram@10080000 { + compatible = "mmio-sram"; + reg = <0x10080000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x10080000 0x10000>; + + smp-sram@0 { + compatible = "rockchip,rk3066-smp-sram"; + reg = <0x0 0x50>; + }; + }; + pinctrl@20008000 { compatible = "rockchip,rk3066a-pinctrl"; reg = <0x20008000 0x150>; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 1a26b03b3649..bb36596ea205 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -60,6 +60,19 @@ interrupts = <GIC_PPI 13 0xf04>; }; + sram: sram@10080000 { + compatible = "mmio-sram"; + reg = <0x10080000 0x8000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x10080000 0x8000>; + + smp-sram@0 { + compatible = "rockchip,rk3066-smp-sram"; + reg = <0x0 0x50>; + }; + }; + pinctrl@20008000 { compatible = "rockchip,rk3188-pinctrl"; reg = <0x20008000 0xa0>, diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi index 0fcbcfd67de2..26e5a968d49d 100644 --- a/arch/arm/boot/dts/rk3xxx.dtsi +++ b/arch/arm/boot/dts/rk3xxx.dtsi @@ -26,6 +26,16 @@ compatible = "simple-bus"; ranges; + scu@1013c000 { + compatible = "arm,cortex-a9-scu"; + reg = <0x1013c000 0x100>; + }; + + pmu@20004000 { + compatible = "rockchip,rk3066-pmu"; + reg = <0x20004000 0x100>; + }; + gic: interrupt-controller@1013d000 { compatible = "arm,cortex-a9-gic"; interrupt-controller; diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 52447c17537a..3d5faf85f51b 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -1228,7 +1228,7 @@ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00600000 0x100000>; interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&usb>, <&uhphs_clk>, <&udphs_clk>, + clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; status = "disabled"; diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi index 0c1e8d871ed1..6cb9b68e2188 100644 --- a/arch/arm/boot/dts/ste-href.dtsi +++ b/arch/arm/boot/dts/ste-href.dtsi @@ -188,7 +188,6 @@ msp2: msp@80117000 { pinctrl-names = "default"; pinctrl-0 = <&msp2_default_mode>; - status = "okay"; }; msp3: msp@80125000 { diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 040bb0eba152..10666ca8aee1 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -315,7 +315,7 @@ ranges; emac: ethernet@01c0b000 { - compatible = "allwinner,sun4i-emac"; + compatible = "allwinner,sun4i-a10-emac"; reg = <0x01c0b000 0x1000>; interrupts = <55>; clocks = <&ahb_gates 17>; @@ -323,7 +323,7 @@ }; mdio@01c0b080 { - compatible = "allwinner,sun4i-mdio"; + compatible = "allwinner,sun4i-a10-mdio"; reg = <0x01c0b080 0x14>; status = "disabled"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index ea16054857a4..64961595e8d6 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -278,7 +278,7 @@ ranges; emac: ethernet@01c0b000 { - compatible = "allwinner,sun4i-emac"; + compatible = "allwinner,sun4i-a10-emac"; reg = <0x01c0b000 0x1000>; interrupts = <55>; clocks = <&ahb_gates 17>; @@ -286,7 +286,7 @@ }; mdio@01c0b080 { - compatible = "allwinner,sun4i-mdio"; + compatible = "allwinner,sun4i-a10-mdio"; reg = <0x01c0b080 0x14>; status = "disabled"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 119f066f0d98..9ff09484847b 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -340,7 +340,7 @@ ranges; emac: ethernet@01c0b000 { - compatible = "allwinner,sun4i-emac"; + compatible = "allwinner,sun4i-a10-emac"; reg = <0x01c0b000 0x1000>; interrupts = <0 55 4>; clocks = <&ahb_gates 17>; @@ -348,7 +348,7 @@ }; mdio@01c0b080 { - compatible = "allwinner,sun4i-mdio"; + compatible = "allwinner,sun4i-a10-mdio"; reg = <0x01c0b080 0x14>; status = "disabled"; #address-cells = <1>; diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 845bc745706b..ee6982976d66 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -29,6 +29,7 @@ CONFIG_ARCH_OMAP3=y CONFIG_ARCH_OMAP4=y CONFIG_SOC_OMAP5=y CONFIG_SOC_AM33XX=y +CONFIG_SOC_DRA7XX=y CONFIG_SOC_AM43XX=y CONFIG_ARCH_ROCKCHIP=y CONFIG_ARCH_SOCFPGA=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 3a0b53d225e7..364ba38e40f3 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -28,6 +28,7 @@ CONFIG_ARCH_OMAP3=y CONFIG_ARCH_OMAP4=y CONFIG_SOC_OMAP5=y CONFIG_SOC_AM33XX=y +CONFIG_SOC_AM43XX=y CONFIG_SOC_DRA7XX=y CONFIG_ARM_THUMBEE=y CONFIG_ARM_ERRATA_411920=y diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index 22a3b9b5d4a1..772435b08207 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -114,6 +114,15 @@ struct smp_operations { #endif }; +struct of_cpu_method { + const char *method; + struct smp_operations *ops; +}; + +#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ + static const struct of_cpu_method __cpu_method_of_table_##name \ + __used __section(__cpu_method_of_table) \ + = { .method = _method, .ops = _ops } /* * set platform specific SMP operations */ diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index f751714d52c1..c7419a585ddc 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -18,6 +18,7 @@ #include <linux/of_fdt.h> #include <linux/of_irq.h> #include <linux/of_platform.h> +#include <linux/smp.h> #include <asm/cputype.h> #include <asm/setup.h> @@ -63,6 +64,34 @@ void __init arm_dt_memblock_reserve(void) } } +#ifdef CONFIG_SMP +extern struct of_cpu_method __cpu_method_of_table_begin[]; +extern struct of_cpu_method __cpu_method_of_table_end[]; + +static int __init set_smp_ops_by_method(struct device_node *node) +{ + const char *method; + struct of_cpu_method *m = __cpu_method_of_table_begin; + + if (of_property_read_string(node, "enable-method", &method)) + return 0; + + for (; m < __cpu_method_of_table_end; m++) + if (!strcmp(m->method, method)) { + smp_set_ops(m->ops); + return 1; + } + + return 0; +} +#else +static inline int set_smp_ops_by_method(struct device_node *node) +{ + return 1; +} +#endif + + /* * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree * and builds the cpu logical map array containing MPIDR values related to @@ -79,6 +108,7 @@ void __init arm_dt_init_cpu_maps(void) * read as 0. */ struct device_node *cpu, *cpus; + int found_method = 0; u32 i, j, cpuidx = 1; u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; @@ -150,8 +180,18 @@ void __init arm_dt_init_cpu_maps(void) } tmp_map[i] = hwid; + + if (!found_method) + found_method = set_smp_ops_by_method(cpu); } + /* + * Fallback to an enable-method in the cpus node if nothing found in + * a cpu node. + */ + if (!found_method) + set_smp_ops_by_method(cpus); + if (!bootcpu_valid) { pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n"); return; diff --git a/arch/arm/mach-clps711x/board-autcpu12.c b/arch/arm/mach-clps711x/board-autcpu12.c index f8d71a89644a..eb945b2a0042 100644 --- a/arch/arm/mach-clps711x/board-autcpu12.c +++ b/arch/arm/mach-clps711x/board-autcpu12.c @@ -265,14 +265,12 @@ static void __init autcpu12_init_late(void) MACHINE_START(AUTCPU12, "autronix autcpu12") /* Maintainer: Thomas Gleixner */ .atag_offset = 0x20000, - .nr_irqs = CLPS711X_NR_IRQS, .map_io = clps711x_map_io, .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, .init_machine = autcpu12_init, .init_late = autcpu12_init_late, - .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/board-cdb89712.c b/arch/arm/mach-clps711x/board-cdb89712.c index a9e38c6bcfb4..e261a47f2aff 100644 --- a/arch/arm/mach-clps711x/board-cdb89712.c +++ b/arch/arm/mach-clps711x/board-cdb89712.c @@ -139,12 +139,10 @@ static void __init cdb89712_init(void) MACHINE_START(CDB89712, "Cirrus-CDB89712") /* Maintainer: Ray Lehtiniemi */ .atag_offset = 0x100, - .nr_irqs = CLPS711X_NR_IRQS, .map_io = clps711x_map_io, .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, .init_machine = cdb89712_init, - .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/board-clep7312.c b/arch/arm/mach-clps711x/board-clep7312.c index b4764246d0f8..221b9de32dd6 100644 --- a/arch/arm/mach-clps711x/board-clep7312.c +++ b/arch/arm/mach-clps711x/board-clep7312.c @@ -36,12 +36,10 @@ fixup_clep7312(struct tag *tags, char **cmdline, struct meminfo *mi) MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") /* Maintainer: Nobody */ .atag_offset = 0x0100, - .nr_irqs = CLPS711X_NR_IRQS, .fixup = fixup_clep7312, .map_io = clps711x_map_io, .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, - .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/board-edb7211.c b/arch/arm/mach-clps711x/board-edb7211.c index fe6184ead896..077609841f14 100644 --- a/arch/arm/mach-clps711x/board-edb7211.c +++ b/arch/arm/mach-clps711x/board-edb7211.c @@ -177,7 +177,6 @@ static void __init edb7211_init_late(void) MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") /* Maintainer: Jon McClintock */ .atag_offset = VIDEORAM_SIZE + 0x100, - .nr_irqs = CLPS711X_NR_IRQS, .fixup = fixup_edb7211, .reserve = edb7211_reserve, .map_io = clps711x_map_io, @@ -186,6 +185,5 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") .init_time = clps711x_timer_init, .init_machine = edb7211_init, .init_late = edb7211_init_late, - .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/board-p720t.c b/arch/arm/mach-clps711x/board-p720t.c index dd81b06f68fe..67b733744ed7 100644 --- a/arch/arm/mach-clps711x/board-p720t.c +++ b/arch/arm/mach-clps711x/board-p720t.c @@ -363,7 +363,6 @@ static void __init p720t_init_late(void) MACHINE_START(P720T, "ARM-Prospector720T") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ .atag_offset = 0x100, - .nr_irqs = CLPS711X_NR_IRQS, .fixup = fixup_p720t, .map_io = clps711x_map_io, .init_early = clps711x_init_early, @@ -371,6 +370,5 @@ MACHINE_START(P720T, "ARM-Prospector720T") .init_time = clps711x_timer_init, .init_machine = p720t_init, .init_late = p720t_init_late, - .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index a1935911e4f1..aee81fa46ccf 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -31,14 +31,14 @@ #include <linux/clk-provider.h> #include <linux/sched_clock.h> -#include <asm/exception.h> -#include <asm/mach/irq.h> #include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/system_misc.h> #include <mach/hardware.h> +#include "common.h" + static struct clk *clk_pll, *clk_bus, *clk_uart, *clk_timerl, *clk_timerh, *clk_tint, *clk_spi; @@ -59,204 +59,9 @@ void __init clps711x_map_io(void) iotable_init(clps711x_io_desc, ARRAY_SIZE(clps711x_io_desc)); } -static void int1_mask(struct irq_data *d) -{ - u32 intmr1; - - intmr1 = clps_readl(INTMR1); - intmr1 &= ~(1 << d->irq); - clps_writel(intmr1, INTMR1); -} - -static void int1_eoi(struct irq_data *d) -{ - switch (d->irq) { - case IRQ_CSINT: clps_writel(0, COEOI); break; - case IRQ_TC1OI: clps_writel(0, TC1EOI); break; - case IRQ_TC2OI: clps_writel(0, TC2EOI); break; - case IRQ_RTCMI: clps_writel(0, RTCEOI); break; - case IRQ_TINT: clps_writel(0, TEOI); break; - case IRQ_UMSINT: clps_writel(0, UMSEOI); break; - } -} - -static void int1_unmask(struct irq_data *d) -{ - u32 intmr1; - - intmr1 = clps_readl(INTMR1); - intmr1 |= 1 << d->irq; - clps_writel(intmr1, INTMR1); -} - -static struct irq_chip int1_chip = { - .name = "Interrupt Vector 1", - .irq_eoi = int1_eoi, - .irq_mask = int1_mask, - .irq_unmask = int1_unmask, -}; - -static void int2_mask(struct irq_data *d) -{ - u32 intmr2; - - intmr2 = clps_readl(INTMR2); - intmr2 &= ~(1 << (d->irq - 16)); - clps_writel(intmr2, INTMR2); -} - -static void int2_eoi(struct irq_data *d) -{ - switch (d->irq) { - case IRQ_KBDINT: clps_writel(0, KBDEOI); break; - } -} - -static void int2_unmask(struct irq_data *d) -{ - u32 intmr2; - - intmr2 = clps_readl(INTMR2); - intmr2 |= 1 << (d->irq - 16); - clps_writel(intmr2, INTMR2); -} - -static struct irq_chip int2_chip = { - .name = "Interrupt Vector 2", - .irq_eoi = int2_eoi, - .irq_mask = int2_mask, - .irq_unmask = int2_unmask, -}; - -static void int3_mask(struct irq_data *d) -{ - u32 intmr3; - - intmr3 = clps_readl(INTMR3); - intmr3 &= ~(1 << (d->irq - 32)); - clps_writel(intmr3, INTMR3); -} - -static void int3_unmask(struct irq_data *d) -{ - u32 intmr3; - - intmr3 = clps_readl(INTMR3); - intmr3 |= 1 << (d->irq - 32); - clps_writel(intmr3, INTMR3); -} - -static struct irq_chip int3_chip = { - .name = "Interrupt Vector 3", - .irq_mask = int3_mask, - .irq_unmask = int3_unmask, -}; - -static struct { - int nr; - struct irq_chip *chip; - irq_flow_handler_t handle; -} clps711x_irqdescs[] __initdata = { - { IRQ_CSINT, &int1_chip, handle_fasteoi_irq, }, - { IRQ_EINT1, &int1_chip, handle_level_irq, }, - { IRQ_EINT2, &int1_chip, handle_level_irq, }, - { IRQ_EINT3, &int1_chip, handle_level_irq, }, - { IRQ_TC1OI, &int1_chip, handle_fasteoi_irq, }, - { IRQ_TC2OI, &int1_chip, handle_fasteoi_irq, }, - { IRQ_RTCMI, &int1_chip, handle_fasteoi_irq, }, - { IRQ_TINT, &int1_chip, handle_fasteoi_irq, }, - { IRQ_UTXINT1, &int1_chip, handle_level_irq, }, - { IRQ_URXINT1, &int1_chip, handle_level_irq, }, - { IRQ_UMSINT, &int1_chip, handle_fasteoi_irq, }, - { IRQ_SSEOTI, &int1_chip, handle_level_irq, }, - { IRQ_KBDINT, &int2_chip, handle_fasteoi_irq, }, - { IRQ_SS2RX, &int2_chip, handle_level_irq, }, - { IRQ_SS2TX, &int2_chip, handle_level_irq, }, - { IRQ_UTXINT2, &int2_chip, handle_level_irq, }, - { IRQ_URXINT2, &int2_chip, handle_level_irq, }, -}; - void __init clps711x_init_irq(void) { - unsigned int i; - - /* Disable interrupts */ - clps_writel(0, INTMR1); - clps_writel(0, INTMR2); - clps_writel(0, INTMR3); - - /* Clear down any pending interrupts */ - clps_writel(0, BLEOI); - clps_writel(0, MCEOI); - clps_writel(0, COEOI); - clps_writel(0, TC1EOI); - clps_writel(0, TC2EOI); - clps_writel(0, RTCEOI); - clps_writel(0, TEOI); - clps_writel(0, UMSEOI); - clps_writel(0, KBDEOI); - clps_writel(0, SRXEOF); - clps_writel(0xffffffff, DAISR); - - for (i = 0; i < ARRAY_SIZE(clps711x_irqdescs); i++) { - irq_set_chip_and_handler(clps711x_irqdescs[i].nr, - clps711x_irqdescs[i].chip, - clps711x_irqdescs[i].handle); - set_irq_flags(clps711x_irqdescs[i].nr, - IRQF_VALID | IRQF_PROBE); - } - - if (IS_ENABLED(CONFIG_FIQ)) { - init_FIQ(0); - irq_set_chip_and_handler(IRQ_DAIINT, &int3_chip, - handle_bad_irq); - set_irq_flags(IRQ_DAIINT, - IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN); - } -} - -static inline u32 fls16(u32 x) -{ - u32 r = 15; - - if (!(x & 0xff00)) { - x <<= 8; - r -= 8; - } - if (!(x & 0xf000)) { - x <<= 4; - r -= 4; - } - if (!(x & 0xc000)) { - x <<= 2; - r -= 2; - } - if (!(x & 0x8000)) - r--; - - return r; -} - -asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs) -{ - do { - u32 irqstat; - void __iomem *base = CLPS711X_VIRT_BASE; - - irqstat = readw_relaxed(base + INTSR1) & - readw_relaxed(base + INTMR1); - if (irqstat) - handle_IRQ(fls16(irqstat), regs); - - irqstat = readw_relaxed(base + INTSR2) & - readw_relaxed(base + INTMR2); - if (irqstat) { - handle_IRQ(fls16(irqstat) + 16, regs); - continue; - } - - break; - } while (1); + clps711x_intc_init(CLPS711X_PHYS_BASE, SZ_16K); } static u64 notrace clps711x_sched_clock_read(void) diff --git a/arch/arm/mach-clps711x/common.h b/arch/arm/mach-clps711x/common.h index 9a6767bfdc47..7489139d5d63 100644 --- a/arch/arm/mach-clps711x/common.h +++ b/arch/arm/mach-clps711x/common.h @@ -6,13 +6,14 @@ #include <linux/reboot.h> -#define CLPS711X_NR_IRQS (33) #define CLPS711X_NR_GPIO (4 * 8 + 3) #define CLPS711X_GPIO(prt, bit) ((prt) * 8 + (bit)) extern void clps711x_map_io(void); extern void clps711x_init_irq(void); extern void clps711x_timer_init(void); -extern void clps711x_handle_irq(struct pt_regs *regs); extern void clps711x_restart(enum reboot_mode mode, const char *cmd); extern void clps711x_init_early(void); + +/* drivers/irqchip/irq-clps711x.c */ +void clps711x_intc_init(phys_addr_t, resource_size_t); diff --git a/arch/arm/mach-clps711x/include/mach/clps711x.h b/arch/arm/mach-clps711x/include/mach/clps711x.h index 0286f4bf9945..eb052a11aa9d 100644 --- a/arch/arm/mach-clps711x/include/mach/clps711x.h +++ b/arch/arm/mach-clps711x/include/mach/clps711x.h @@ -40,8 +40,6 @@ #define MEMCFG1 (0x0180) #define MEMCFG2 (0x01c0) #define DRFPR (0x0200) -#define INTSR1 (0x0240) -#define INTMR1 (0x0280) #define LCDCON (0x02c0) #define TC1D (0x0300) #define TC2D (0x0340) @@ -55,28 +53,16 @@ #define PALLSW (0x0540) #define PALMSW (0x0580) #define STFCLR (0x05c0) -#define BLEOI (0x0600) -#define MCEOI (0x0640) -#define TEOI (0x0680) -#define TC1EOI (0x06c0) -#define TC2EOI (0x0700) -#define RTCEOI (0x0740) -#define UMSEOI (0x0780) -#define COEOI (0x07c0) #define HALT (0x0800) #define STDBY (0x0840) #define FBADDR (0x1000) #define SYSCON2 (0x1100) #define SYSFLG2 (0x1140) -#define INTSR2 (0x1240) -#define INTMR2 (0x1280) #define UARTDR2 (0x1480) #define UBRLCR2 (0x14c0) #define SS2DR (0x1500) -#define SRXEOF (0x1600) #define SS2POP (0x16c0) -#define KBDEOI (0x1700) #define DAIR (0x2000) #define DAIDR0 (0x2040) @@ -84,8 +70,6 @@ #define DAIDR2 (0x20c0) #define DAISR (0x2100) #define SYSCON3 (0x2200) -#define INTSR3 (0x2240) -#define INTMR3 (0x2280) #define LEDFLSH (0x22c0) #define SDCONF (0x2300) #define SDRFPR (0x2340) diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig index 8f4649b301b2..1abae5f6a418 100644 --- a/arch/arm/mach-hisi/Kconfig +++ b/arch/arm/mach-hisi/Kconfig @@ -8,7 +8,7 @@ config ARCH_HI3xxx select CLKSRC_OF select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU - select HAVE_ARM_TWD + select HAVE_ARM_TWD if SMP select HAVE_SMP select PINCTRL select PINCTRL_SINGLE diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index af2e582d2b74..4d677f442539 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -482,6 +482,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) if (IS_ENABLED(CONFIG_PCI_IMX6)) clk_set_parent(clk[lvds1_sel], clk[sata_ref]); + /* Set initial power mode */ + imx6q_set_lpm(WAIT_CLOCKED); + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); base = of_iomap(np, 0); WARN_ON(!base); diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index 3781a1853998..4c86f3035205 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -266,6 +266,9 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) /* Audio-related clocks configuration */ clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]); + /* Set initial power mode */ + imx6q_set_lpm(WAIT_CLOCKED); + np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt"); base = of_iomap(np, 0); WARN_ON(!base); diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c index 9d47adc078aa..7a9b98589db7 100644 --- a/arch/arm/mach-imx/pm-imx6q.c +++ b/arch/arm/mach-imx/pm-imx6q.c @@ -236,8 +236,6 @@ void __init imx6q_pm_init(void) regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT, IMX6Q_GPR1_GINT); - /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); suspend_set_ops(&imx6q_pm_ops); } diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig index ba470d64493b..3795ae28a613 100644 --- a/arch/arm/mach-moxart/Kconfig +++ b/arch/arm/mach-moxart/Kconfig @@ -2,7 +2,6 @@ config ARCH_MOXART bool "MOXA ART SoC" if ARCH_MULTI_V4T select CPU_FA526 select ARM_DMA_MEM_BUFFERABLE - select DMA_OF select USE_OF select CLKSRC_OF select CLKSRC_MMIO diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 9625cf378931..a7f959e58c3d 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -1,50 +1,9 @@ -config ARCH_MSM - bool - -config ARCH_MSM_DT - bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7 - select ARCH_MSM - select ARCH_REQUIRE_GPIOLIB - select CLKSRC_OF - select GENERIC_CLOCKEVENTS - help - Support for Qualcomm's devicetree based MSM systems. - if ARCH_MSM -menu "Qualcomm MSM SoC Selection" - depends on ARCH_MSM_DT - -config ARCH_MSM8X60 - bool "Enable support for MSM8X60" - select ARM_GIC - select CPU_V7 - select HAVE_SMP - select MSM_SCM if SMP - select MSM_TIMER - -config ARCH_MSM8960 - bool "Enable support for MSM8960" - select ARM_GIC - select CPU_V7 - select HAVE_SMP - select MSM_SCM if SMP - select MSM_TIMER - -config ARCH_MSM8974 - bool "Enable support for MSM8974" - select ARM_GIC - select CPU_V7 - select HAVE_ARM_ARCH_TIMER - select HAVE_SMP - select MSM_SCM if SMP - -endmenu - choice prompt "Qualcomm MSM SoC Type" default ARCH_MSM7X00A - depends on ARCH_MSM_NODT + depends on ARCH_MSM config ARCH_MSM7X00A bool "MSM7x00A / MSM7x01A" @@ -54,7 +13,7 @@ config ARCH_MSM7X00A select MACH_TROUT if !MACH_HALIBUT select MSM_PROC_COMM select MSM_SMD - select MSM_TIMER + select CLKSRC_QCOM select MSM_SMD_PKG3 config ARCH_MSM7X30 @@ -66,7 +25,7 @@ config ARCH_MSM7X30 select MSM_GPIOMUX select MSM_PROC_COMM select MSM_SMD - select MSM_TIMER + select CLKSRC_QCOM select MSM_VIC config ARCH_QSD8X50 @@ -78,7 +37,7 @@ config ARCH_QSD8X50 select MSM_GPIOMUX select MSM_PROC_COMM select MSM_SMD - select MSM_TIMER + select CLKSRC_QCOM select MSM_VIC endchoice @@ -99,7 +58,7 @@ config MSM_VIC bool menu "Qualcomm MSM Board Type" - depends on ARCH_MSM_NODT + depends on ARCH_MSM config MACH_HALIBUT depends on ARCH_MSM @@ -153,7 +112,4 @@ config MSM_GPIOMUX config MSM_SCM bool -config MSM_TIMER - bool - endif diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 8e307a10d3c3..27c078a568df 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,4 +1,3 @@ -obj-$(CONFIG_MSM_TIMER) += timer.o obj-$(CONFIG_MSM_PROC_COMM) += clock.o obj-$(CONFIG_MSM_VIC) += irq-vic.o @@ -14,18 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MSM_SMD) += last_radio_log.o -obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o - -CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) - -obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o -obj-$(CONFIG_SMP) += headsmp.o platsmp.o obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o -obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o diff --git a/arch/arm/mach-msm/common.h b/arch/arm/mach-msm/common.h index 33c7725adae2..572479a3c7be 100644 --- a/arch/arm/mach-msm/common.h +++ b/arch/arm/mach-msm/common.h @@ -23,9 +23,6 @@ extern void msm_map_qsd8x50_io(void); extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size, unsigned int mtype, void *caller); -extern struct smp_operations msm_smp_ops; -extern void msm_cpu_die(unsigned int cpu); - struct msm_mmc_platform_data; extern void msm_add_devices(void); diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S deleted file mode 100644 index 6c62c3f82fe6..000000000000 --- a/arch/arm/mach-msm/headsmp.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * linux/arch/arm/mach-realview/headsmp.S - * - * Copyright (c) 2003 ARM Limited - * All Rights Reserved - * - * 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/linkage.h> -#include <linux/init.h> - -/* - * MSM specific entry point for secondary CPUs. This provides - * a "holding pen" into which all secondary cores are held until we're - * ready for them to initialise. - */ -ENTRY(msm_secondary_startup) - mrc p15, 0, r0, c0, c0, 5 - and r0, r0, #15 - adr r4, 1f - ldmia r4, {r5, r6} - sub r4, r4, r5 - add r6, r6, r4 -pen: ldr r7, [r6] - cmp r7, r0 - bne pen - - /* - * we've been released from the holding pen: secondary_stack - * should now contain the SVC stack for this core - */ - b secondary_startup -ENDPROC(msm_secondary_startup) - - .align -1: .long . - .long pen_release diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c deleted file mode 100644 index 326a87261f9a..000000000000 --- a/arch/arm/mach-msm/hotplug.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2002 ARM Ltd. - * All Rights Reserved - * - * 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/errno.h> -#include <linux/smp.h> - -#include <asm/smp_plat.h> - -#include "common.h" - -static inline void cpu_enter_lowpower(void) -{ -} - -static inline void cpu_leave_lowpower(void) -{ -} - -static inline void platform_do_lowpower(unsigned int cpu) -{ - /* Just enter wfi for now. TODO: Properly shut off the cpu. */ - for (;;) { - /* - * here's the WFI - */ - asm("wfi" - : - : - : "memory", "cc"); - - if (pen_release == cpu_logical_map(cpu)) { - /* - * OK, proper wakeup, we're done - */ - break; - } - - /* - * getting here, means that we have come out of WFI without - * having been woken up - this shouldn't happen - * - * The trouble is, letting people know about this is not really - * possible, since we are currently running incoherently, and - * therefore cannot safely call printk() or anything else - */ - pr_debug("CPU%u: spurious wakeup call\n", cpu); - } -} - -/* - * platform-specific code to shutdown a CPU - * - * Called with IRQs disabled - */ -void __ref msm_cpu_die(unsigned int cpu) -{ - /* - * we're ready for shutdown now, so do it - */ - cpu_enter_lowpower(); - platform_do_lowpower(cpu); - - /* - * bring this CPU back into the world of cache - * coherency, and then restore interrupts - */ - cpu_leave_lowpower(); -} diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c deleted file mode 100644 index f10a1f58fde9..000000000000 --- a/arch/arm/mach-msm/platsmp.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2002 ARM Ltd. - * All Rights Reserved - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/jiffies.h> -#include <linux/smp.h> -#include <linux/io.h> - -#include <asm/cacheflush.h> -#include <asm/cputype.h> -#include <asm/mach-types.h> -#include <asm/smp_plat.h> - -#include "scm-boot.h" -#include "common.h" - -#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0 -#define SCSS_CPU1CORE_RESET 0xD80 -#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64 - -extern void msm_secondary_startup(void); - -static DEFINE_SPINLOCK(boot_lock); - -static inline int get_core_count(void) -{ - /* 1 + the PART[1:0] field of MIDR */ - return ((read_cpuid_id() >> 4) & 3) + 1; -} - -static void msm_secondary_init(unsigned int cpu) -{ - /* - * let the primary processor know we're out of the - * pen, then head off into the C entry point - */ - pen_release = -1; - smp_wmb(); - - /* - * Synchronise with the boot thread. - */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); -} - -static void prepare_cold_cpu(unsigned int cpu) -{ - int ret; - ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup), - SCM_FLAG_COLDBOOT_CPU1); - if (ret == 0) { - void __iomem *sc1_base_ptr; - sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2); - if (sc1_base_ptr) { - writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL); - writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET); - writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP); - iounmap(sc1_base_ptr); - } - } else - printk(KERN_DEBUG "Failed to set secondary core boot " - "address\n"); -} - -static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - unsigned long timeout; - static int cold_boot_done; - - /* Only need to bring cpu out of reset this way once */ - if (cold_boot_done == false) { - prepare_cold_cpu(cpu); - cold_boot_done = true; - } - - /* - * set synchronisation state between this boot processor - * and the secondary one - */ - spin_lock(&boot_lock); - - /* - * The secondary processor is waiting to be released from - * the holding pen - release it, then wait for it to flag - * that it has been released by resetting pen_release. - * - * Note that "pen_release" is the hardware CPU ID, whereas - * "cpu" is Linux's internal ID. - */ - pen_release = cpu_logical_map(cpu); - sync_cache_w(&pen_release); - - /* - * Send the secondary CPU a soft interrupt, thereby causing - * the boot monitor to read the system wide flags register, - * and branch to the address found there. - */ - arch_send_wakeup_ipi_mask(cpumask_of(cpu)); - - timeout = jiffies + (1 * HZ); - while (time_before(jiffies, timeout)) { - smp_rmb(); - if (pen_release == -1) - break; - - udelay(10); - } - - /* - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ - spin_unlock(&boot_lock); - - return pen_release != -1 ? -ENOSYS : 0; -} - -/* - * Initialise the CPU possible map early - this describes the CPUs - * which may be present or become present in the system. The msm8x60 - * does not support the ARM SCU, so just set the possible cpu mask to - * NR_CPUS. - */ -static void __init msm_smp_init_cpus(void) -{ - unsigned int i, ncores = get_core_count(); - - if (ncores > nr_cpu_ids) { - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", - ncores, nr_cpu_ids); - ncores = nr_cpu_ids; - } - - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); -} - -static void __init msm_smp_prepare_cpus(unsigned int max_cpus) -{ -} - -struct smp_operations msm_smp_ops __initdata = { - .smp_init_cpus = msm_smp_init_cpus, - .smp_prepare_cpus = msm_smp_prepare_cpus, - .smp_secondary_init = msm_secondary_init, - .smp_boot_secondary = msm_boot_secondary, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_die = msm_cpu_die, -#endif -}; diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c deleted file mode 100644 index fd1644987534..000000000000 --- a/arch/arm/mach-msm/timer.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include <linux/clocksource.h> -#include <linux/clockchips.h> -#include <linux/cpu.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <linux/sched_clock.h> - -#include <asm/mach/time.h> - -#include "common.h" - -#define TIMER_MATCH_VAL 0x0000 -#define TIMER_COUNT_VAL 0x0004 -#define TIMER_ENABLE 0x0008 -#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1) -#define TIMER_ENABLE_EN BIT(0) -#define TIMER_CLEAR 0x000C -#define DGT_CLK_CTL 0x10 -#define DGT_CLK_CTL_DIV_4 0x3 -#define TIMER_STS_GPT0_CLR_PEND BIT(10) - -#define GPT_HZ 32768 - -#define MSM_DGT_SHIFT 5 - -static void __iomem *event_base; -static void __iomem *sts_base; - -static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = dev_id; - /* Stop the timer tick */ - if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { - u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); - ctrl &= ~TIMER_ENABLE_EN; - writel_relaxed(ctrl, event_base + TIMER_ENABLE); - } - evt->event_handler(evt); - return IRQ_HANDLED; -} - -static int msm_timer_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); - - ctrl &= ~TIMER_ENABLE_EN; - writel_relaxed(ctrl, event_base + TIMER_ENABLE); - - writel_relaxed(ctrl, event_base + TIMER_CLEAR); - writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); - - if (sts_base) - while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND) - cpu_relax(); - - writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); - return 0; -} - -static void msm_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - u32 ctrl; - - ctrl = readl_relaxed(event_base + TIMER_ENABLE); - ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN); - - switch (mode) { - case CLOCK_EVT_MODE_RESUME: - case CLOCK_EVT_MODE_PERIODIC: - break; - case CLOCK_EVT_MODE_ONESHOT: - /* Timer is enabled in set_next_event */ - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - break; - } - writel_relaxed(ctrl, event_base + TIMER_ENABLE); -} - -static struct clock_event_device __percpu *msm_evt; - -static void __iomem *source_base; - -static notrace cycle_t msm_read_timer_count(struct clocksource *cs) -{ - return readl_relaxed(source_base + TIMER_COUNT_VAL); -} - -static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs) -{ - /* - * Shift timer count down by a constant due to unreliable lower bits - * on some targets. - */ - return msm_read_timer_count(cs) >> MSM_DGT_SHIFT; -} - -static struct clocksource msm_clocksource = { - .name = "dg_timer", - .rating = 300, - .read = msm_read_timer_count, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int msm_timer_irq; -static int msm_timer_has_ppi; - -static int msm_local_timer_setup(struct clock_event_device *evt) -{ - int cpu = smp_processor_id(); - int err; - - evt->irq = msm_timer_irq; - evt->name = "msm_timer"; - evt->features = CLOCK_EVT_FEAT_ONESHOT; - evt->rating = 200; - evt->set_mode = msm_timer_set_mode; - evt->set_next_event = msm_timer_set_next_event; - evt->cpumask = cpumask_of(cpu); - - clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff); - - if (msm_timer_has_ppi) { - enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING); - } else { - err = request_irq(evt->irq, msm_timer_interrupt, - IRQF_TIMER | IRQF_NOBALANCING | - IRQF_TRIGGER_RISING, "gp_timer", evt); - if (err) - pr_err("request_irq failed\n"); - } - - return 0; -} - -static void msm_local_timer_stop(struct clock_event_device *evt) -{ - evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); - disable_percpu_irq(evt->irq); -} - -static int msm_timer_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) -{ - /* - * Grab cpu pointer in each case to avoid spurious - * preemptible warnings - */ - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_STARTING: - msm_local_timer_setup(this_cpu_ptr(msm_evt)); - break; - case CPU_DYING: - msm_local_timer_stop(this_cpu_ptr(msm_evt)); - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block msm_timer_cpu_nb = { - .notifier_call = msm_timer_cpu_notify, -}; - -static u64 notrace msm_sched_clock_read(void) -{ - return msm_clocksource.read(&msm_clocksource); -} - -static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, - bool percpu) -{ - struct clocksource *cs = &msm_clocksource; - int res = 0; - - msm_timer_irq = irq; - msm_timer_has_ppi = percpu; - - msm_evt = alloc_percpu(struct clock_event_device); - if (!msm_evt) { - pr_err("memory allocation failed for clockevents\n"); - goto err; - } - - if (percpu) - res = request_percpu_irq(irq, msm_timer_interrupt, - "gp_timer", msm_evt); - - if (res) { - pr_err("request_percpu_irq failed\n"); - } else { - res = register_cpu_notifier(&msm_timer_cpu_nb); - if (res) { - free_percpu_irq(irq, msm_evt); - goto err; - } - - /* Immediately configure the timer on the boot CPU */ - msm_local_timer_setup(__this_cpu_ptr(msm_evt)); - } - -err: - writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); - res = clocksource_register_hz(cs, dgt_hz); - if (res) - pr_err("clocksource_register failed\n"); - sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); -} - -#ifdef CONFIG_OF -static void __init msm_dt_timer_init(struct device_node *np) -{ - u32 freq; - int irq; - struct resource res; - u32 percpu_offset; - void __iomem *base; - void __iomem *cpu0_base; - - base = of_iomap(np, 0); - if (!base) { - pr_err("Failed to map event base\n"); - return; - } - - /* We use GPT0 for the clockevent */ - irq = irq_of_parse_and_map(np, 1); - if (irq <= 0) { - pr_err("Can't get irq\n"); - return; - } - - /* We use CPU0's DGT for the clocksource */ - if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) - percpu_offset = 0; - - if (of_address_to_resource(np, 0, &res)) { - pr_err("Failed to parse DGT resource\n"); - return; - } - - cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res)); - if (!cpu0_base) { - pr_err("Failed to map source base\n"); - return; - } - - if (of_property_read_u32(np, "clock-frequency", &freq)) { - pr_err("Unknown frequency\n"); - return; - } - - event_base = base + 0x4; - sts_base = base + 0x88; - source_base = cpu0_base + 0x24; - freq /= 4; - writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); - - msm_timer_init(freq, 32, irq, !!percpu_offset); -} -CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); -CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); -#endif - -static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source, - u32 sts) -{ - void __iomem *base; - - base = ioremap(addr, SZ_256); - if (!base) { - pr_err("Failed to map timer base\n"); - return -ENOMEM; - } - event_base = base + event; - source_base = base + source; - if (sts) - sts_base = base + sts; - - return 0; -} - -void __init msm7x01_timer_init(void) -{ - struct clocksource *cs = &msm_clocksource; - - if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0)) - return; - cs->read = msm_read_timer_count_shift; - cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)); - /* 600 KHz */ - msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7, - false); -} - -void __init msm7x30_timer_init(void) -{ - if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80)) - return; - msm_timer_init(24576000 / 4, 32, 1, false); -} - -void __init qsd8x50_timer_init(void) -{ - if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34)) - return; - msm_timer_init(19200000 / 4, 32, 7, false); -} diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 5e269d7263ce..884b275ab056 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -21,26 +21,55 @@ if ARCH_MVEBU menu "Marvell SOC with device tree" -config MACH_ARMADA_370_XP +config MACH_MVEBU_V7 bool select ARMADA_370_XP_TIMER select HAVE_SMP select CACHE_L2X0 - select CPU_PJ4B config MACH_ARMADA_370 bool "Marvell Armada 370 boards" select ARMADA_370_CLK - select MACH_ARMADA_370_XP + select CPU_PJ4B + select MACH_MVEBU_V7 select PINCTRL_ARMADA_370 help Say 'Y' here if you want your kernel to support boards based on the Marvell Armada 370 SoC with device tree. +config MACH_ARMADA_375 + bool "Marvell Armada 375 boards" + select ARM_ERRATA_720789 + select ARM_ERRATA_753970 + select ARM_GIC + select ARMADA_375_CLK + select CPU_V7 + select MACH_MVEBU_V7 + select NEON + select PINCTRL_ARMADA_375 + help + Say 'Y' here if you want your kernel to support boards based + on the Marvell Armada 375 SoC with device tree. + +config MACH_ARMADA_38X + bool "Marvell Armada 380/385 boards" + select ARM_ERRATA_720789 + select ARM_ERRATA_753970 + select ARM_GIC + select ARMADA_38X_CLK + select CPU_V7 + select MACH_MVEBU_V7 + select NEON + select PINCTRL_ARMADA_38X + help + Say 'Y' here if you want your kernel to support boards based + on the Marvell Armada 380/385 SoC with device tree. + config MACH_ARMADA_XP bool "Marvell Armada XP boards" select ARMADA_XP_CLK - select MACH_ARMADA_370_XP + select CPU_PJ4B + select MACH_MVEBU_V7 select PINCTRL_ARMADA_XP help Say 'Y' here if you want your kernel to support boards based diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 878aebe98dcc..2c1db29db2ca 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -4,7 +4,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ AFLAGS_coherency_ll.o := -Wa,-march=armv7-a obj-y += system-controller.o mvebu-soc-id.o -obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o +obj-$(CONFIG_MACH_MVEBU_V7) += board-v7.o obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/board-v7.c index f6c9d1d85c14..746134ecdfc2 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/board-v7.c @@ -31,12 +31,28 @@ #include "coherency.h" #include "mvebu-soc-id.h" -static void __init armada_370_xp_map_io(void) +/* + * Early versions of Armada 375 SoC have a bug where the BootROM + * leaves an external data abort pending. The kernel is hit by this + * data abort as soon as it enters userspace, because it unmasks the + * data aborts at this moment. We register a custom abort handler + * below to ignore the first data abort to work around this + * problem. + */ +static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr, + struct pt_regs *regs) { - debug_ll_io_init(); + static int ignore_first; + + if (!ignore_first && fsr == 0x1406) { + ignore_first = 1; + return 0; + } + + return 1; } -static void __init armada_370_xp_timer_and_clk_init(void) +static void __init mvebu_timer_and_clk_init(void) { of_clk_init(NULL); clocksource_of_init(); @@ -45,6 +61,10 @@ static void __init armada_370_xp_timer_and_clk_init(void) #ifdef CONFIG_CACHE_L2X0 l2x0_of_init(0, ~0UL); #endif + + if (of_machine_is_compatible("marvell,armada375")) + hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0, + "imprecise external abort"); } static void __init i2c_quirk(void) @@ -75,7 +95,7 @@ static void __init i2c_quirk(void) return; } -static void __init armada_370_xp_dt_init(void) +static void __init mvebu_dt_init(void) { if (of_machine_is_compatible("plathome,openblocks-ax3-4")) i2c_quirk(); @@ -87,11 +107,33 @@ static const char * const armada_370_xp_dt_compat[] = { NULL, }; -DT_MACHINE_START(ARMADA_XP_DT, "Marvell Armada 370/XP (Device Tree)") +DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)") .smp = smp_ops(armada_xp_smp_ops), - .init_machine = armada_370_xp_dt_init, - .map_io = armada_370_xp_map_io, - .init_time = armada_370_xp_timer_and_clk_init, + .init_machine = mvebu_dt_init, + .init_time = mvebu_timer_and_clk_init, .restart = mvebu_restart, .dt_compat = armada_370_xp_dt_compat, MACHINE_END + +static const char * const armada_375_dt_compat[] = { + "marvell,armada375", + NULL, +}; + +DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)") + .init_time = mvebu_timer_and_clk_init, + .restart = mvebu_restart, + .dt_compat = armada_375_dt_compat, +MACHINE_END + +static const char * const armada_38x_dt_compat[] = { + "marvell,armada380", + "marvell,armada385", + NULL, +}; + +DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)") + .init_time = mvebu_timer_and_clk_init, + .restart = mvebu_restart, + .dt_compat = armada_38x_dt_compat, +MACHINE_END diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c index a7fb89a5b5d9..614ba6832ff3 100644 --- a/arch/arm/mach-mvebu/system-controller.c +++ b/arch/arm/mach-mvebu/system-controller.c @@ -1,5 +1,5 @@ /* - * System controller support for Armada 370 and XP platforms. + * System controller support for Armada 370, 375 and XP platforms. * * Copyright (C) 2012 Marvell * @@ -11,7 +11,7 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. * - * The Armada 370 and Armada XP SoCs both have a range of + * The Armada 370, 375 and Armada XP SoCs have a range of * miscellaneous registers, that do not belong to a particular device, * but rather provide system-level features. This basic * system-controller driver provides a device tree binding for those @@ -47,6 +47,13 @@ static const struct mvebu_system_controller armada_370_xp_system_controller = { .system_soft_reset = 0x1, }; +static const struct mvebu_system_controller armada_375_system_controller = { + .rstoutn_mask_offset = 0x54, + .system_soft_reset_offset = 0x58, + .rstoutn_mask_reset_out_en = 0x1, + .system_soft_reset = 0x1, +}; + static const struct mvebu_system_controller orion_system_controller = { .rstoutn_mask_offset = 0x108, .system_soft_reset_offset = 0x10c, @@ -54,13 +61,16 @@ static const struct mvebu_system_controller orion_system_controller = { .system_soft_reset = 0x1, }; -static struct of_device_id of_system_controller_table[] = { +static const struct of_device_id of_system_controller_table[] = { { .compatible = "marvell,orion-system-controller", .data = (void *) &orion_system_controller, }, { .compatible = "marvell,armada-370-xp-system-controller", .data = (void *) &armada_370_xp_system_controller, + }, { + .compatible = "marvell,armada-375-system-controller", + .data = (void *) &armada_375_system_controller, }, { /* end of list */ }, }; @@ -90,13 +100,12 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd) static int __init mvebu_system_controller_init(void) { + const struct of_device_id *match; struct device_node *np; - np = of_find_matching_node(NULL, of_system_controller_table); + np = of_find_matching_node_and_match(NULL, of_system_controller_table, + &match); if (np) { - const struct of_device_id *match = - of_match_node(of_system_controller_table, np); - BUG_ON(!match); system_controller_base = of_iomap(np, 0); mvebu_sc = (struct mvebu_system_controller *)match->data; of_node_put(np); diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 653b489479e0..40fd5c31b594 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -54,7 +54,7 @@ config SOC_OMAP5 select ARM_GIC select CPU_V7 select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP select HAVE_ARM_ARCH_TIMER select ARM_ERRATA_798181 if SMP @@ -165,12 +165,6 @@ config SOC_TI81XX depends on ARCH_OMAP3 default y -config OMAP_PACKAGE_ZAF - bool - -config OMAP_PACKAGE_ZAC - bool - config OMAP_PACKAGE_CBC bool @@ -284,7 +278,6 @@ config MACH_NOKIA_N8X0 select MACH_NOKIA_N800 select MACH_NOKIA_N810 select MACH_NOKIA_N810_WIMAX - select OMAP_PACKAGE_ZAC config MACH_NOKIA_RX51 bool "Nokia N900 (RX-51) phone" diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index e94eb0fe95aa..bc6013fbb773 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -229,7 +229,7 @@ DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)") .init_late = am43xx_init_late, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, - .init_time = omap3_sync32k_timer_init, + .init_time = omap3_gptimer_timer_init, .dt_compat = am43_boards_compat, .restart = omap44xx_restart, MACHINE_END diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 9428c5f9d4f2..157412e4273a 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -465,8 +465,18 @@ void __init omap3xxx_check_revision(void) } break; case 0xb98c: - omap_revision = AM437X_REV_ES1_0; - cpu_rev = "1.0"; + switch (rev) { + case 0: + omap_revision = AM437X_REV_ES1_0; + cpu_rev = "1.0"; + break; + case 1: + /* FALLTHROUGH */ + default: + omap_revision = AM437X_REV_ES1_1; + cpu_rev = "1.1"; + break; + } break; case 0xb8f2: switch (rev) { @@ -657,6 +667,8 @@ static const char * __init omap_get_family(void) return kasprintf(GFP_KERNEL, "OMAP4"); else if (soc_is_omap54xx()) return kasprintf(GFP_KERNEL, "OMAP5"); + else if (soc_is_am43xx()) + return kasprintf(GFP_KERNEL, "AM43xx"); else return kasprintf(GFP_KERNEL, "Unknown"); } diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index d408b15b4fbf..d9714113a01a 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -613,6 +613,7 @@ void __init am43xx_init_early(void) omap_prm_base_init(); omap_cm_base_init(); omap3xxx_check_revision(); + am33xx_check_features(); am43xx_powerdomains_init(); am43xx_clockdomains_init(); am43xx_hwmod_init(); diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index a722330d4d53..d121fb6df4e6 100644 --- a/arch/arm/mach-omap2/mux.h +++ b/arch/arm/mach-omap2/mux.h @@ -63,9 +63,6 @@ #define OMAP_PACKAGE_CUS 5 /* 423-pin 0.65 */ #define OMAP_PACKAGE_CBB 4 /* 515-pin 0.40 0.50 */ #define OMAP_PACKAGE_CBC 3 /* 515-pin 0.50 0.65 */ -#define OMAP_PACKAGE_ZAC 2 /* 24xx 447-pin POP */ -#define OMAP_PACKAGE_ZAF 1 /* 2420 447-pin SIP */ - #define OMAP_MUX_NR_MODES 8 /* Available modes */ #define OMAP_MUX_NR_SIDES 2 /* Bottom & top */ diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 076bd90a6ce0..30abcc8b20e0 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -438,7 +438,8 @@ IS_OMAP_TYPE(3430, 0x3430) #define AM335X_REV_ES2_1 (AM335X_CLASS | (0x2 << 8)) #define AM437X_CLASS 0x43700000 -#define AM437X_REV_ES1_0 AM437X_CLASS +#define AM437X_REV_ES1_0 (AM437X_CLASS | (0x10 << 8)) +#define AM437X_REV_ES1_1 (AM437X_CLASS | (0x11 << 8)) #define OMAP443X_CLASS 0x44300044 #define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8)) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 74044aaf438b..b62de9f9d05c 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -604,7 +604,8 @@ OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure", 2, "timer_sys_ck", NULL); #endif /* CONFIG_ARCH_OMAP3 */ -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \ + defined(CONFIG_SOC_AM43XX) OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL, 1, "timer_sys_ck", "ti,timer-alwon"); #endif diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c index c9f309ae88c5..8b90c4f2d430 100644 --- a/arch/arm/mach-pxa/am300epd.c +++ b/arch/arm/mach-pxa/am300epd.c @@ -30,6 +30,7 @@ #include <mach/gumstix.h> #include <mach/mfp-pxa25x.h> +#include <mach/irqs.h> #include <linux/platform_data/video-pxafb.h> #include "generic.h" diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h index 954641e6c8b1..1b0825911e62 100644 --- a/arch/arm/mach-pxa/include/mach/balloon3.h +++ b/arch/arm/mach-pxa/include/mach/balloon3.h @@ -14,6 +14,8 @@ #ifndef ASM_ARCH_BALLOON3_H #define ASM_ARCH_BALLOON3_H +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ + enum balloon3_features { BALLOON3_FEATURE_OHCI, BALLOON3_FEATURE_MMC, diff --git a/arch/arm/mach-pxa/include/mach/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h index f3c3493b468d..c030d955bbd7 100644 --- a/arch/arm/mach-pxa/include/mach/corgi.h +++ b/arch/arm/mach-pxa/include/mach/corgi.h @@ -13,6 +13,7 @@ #ifndef __ASM_ARCH_CORGI_H #define __ASM_ARCH_CORGI_H 1 +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ /* * Corgi (Non Standard) GPIO Definitions diff --git a/arch/arm/mach-pxa/include/mach/csb726.h b/arch/arm/mach-pxa/include/mach/csb726.h index 2628e7b72116..00cfbbbf73f7 100644 --- a/arch/arm/mach-pxa/include/mach/csb726.h +++ b/arch/arm/mach-pxa/include/mach/csb726.h @@ -11,6 +11,8 @@ #ifndef CSB726_H #define CSB726_H +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + #define CSB726_GPIO_IRQ_LAN 52 #define CSB726_GPIO_IRQ_SM501 53 #define CSB726_GPIO_MMC_DETECT 100 diff --git a/arch/arm/mach-pxa/include/mach/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h index dba14b6503ad..f7df27bbb42e 100644 --- a/arch/arm/mach-pxa/include/mach/gumstix.h +++ b/arch/arm/mach-pxa/include/mach/gumstix.h @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ /* BTRESET - Reset line to Bluetooth module, active low signal. */ #define GPIO_GUMSTIX_BTRESET 7 diff --git a/arch/arm/mach-pxa/include/mach/idp.h b/arch/arm/mach-pxa/include/mach/idp.h index 22a96f87232b..7e63f4680271 100644 --- a/arch/arm/mach-pxa/include/mach/idp.h +++ b/arch/arm/mach-pxa/include/mach/idp.h @@ -23,6 +23,7 @@ * IDP hardware. */ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ #define IDP_FLASH_PHYS (PXA_CS0_PHYS) #define IDP_ALT_FLASH_PHYS (PXA_CS1_PHYS) diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h index 2c4471336570..b184f296023b 100644 --- a/arch/arm/mach-pxa/include/mach/palmld.h +++ b/arch/arm/mach-pxa/include/mach/palmld.h @@ -13,6 +13,8 @@ #ifndef _INCLUDE_PALMLD_H_ #define _INCLUDE_PALMLD_H_ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /** HERE ARE GPIOs **/ /* GPIOs */ diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h index 0bd4f036c72f..e342c5921405 100644 --- a/arch/arm/mach-pxa/include/mach/palmt5.h +++ b/arch/arm/mach-pxa/include/mach/palmt5.h @@ -15,6 +15,8 @@ #ifndef _INCLUDE_PALMT5_H_ #define _INCLUDE_PALMT5_H_ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /** HERE ARE GPIOs **/ /* GPIOs */ diff --git a/arch/arm/mach-pxa/include/mach/palmtc.h b/arch/arm/mach-pxa/include/mach/palmtc.h index c383a21680b6..81c727b3cfd2 100644 --- a/arch/arm/mach-pxa/include/mach/palmtc.h +++ b/arch/arm/mach-pxa/include/mach/palmtc.h @@ -16,6 +16,8 @@ #ifndef _INCLUDE_PALMTC_H_ #define _INCLUDE_PALMTC_H_ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /** HERE ARE GPIOs **/ /* GPIOs */ diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h index f2e530380253..92bc1f05300d 100644 --- a/arch/arm/mach-pxa/include/mach/palmtx.h +++ b/arch/arm/mach-pxa/include/mach/palmtx.h @@ -16,6 +16,8 @@ #ifndef _INCLUDE_PALMTX_H_ #define _INCLUDE_PALMTX_H_ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /** HERE ARE GPIOs **/ /* GPIOs */ diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h index 6bf28de228bd..86ebd7b6c960 100644 --- a/arch/arm/mach-pxa/include/mach/pcm027.h +++ b/arch/arm/mach-pxa/include/mach/pcm027.h @@ -23,6 +23,8 @@ * Definitions of CPU card resources only */ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /* phyCORE-PXA270 (PCM027) Interrupts */ #define PCM027_IRQ(x) (IRQ_BOARD_START + (x)) #define PCM027_BTDET_IRQ PCM027_IRQ(0) diff --git a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h index 0260aaa2fc17..7e544c14967e 100644 --- a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h +++ b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h @@ -20,6 +20,7 @@ */ #include <mach/pcm027.h> +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ /* * definitions relevant only when the PCM-990 diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h index f32ff75dcca8..b56b19351a03 100644 --- a/arch/arm/mach-pxa/include/mach/poodle.h +++ b/arch/arm/mach-pxa/include/mach/poodle.h @@ -15,6 +15,8 @@ #ifndef __ASM_ARCH_POODLE_H #define __ASM_ARCH_POODLE_H 1 +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /* * GPIOs */ diff --git a/arch/arm/mach-pxa/include/mach/spitz.h b/arch/arm/mach-pxa/include/mach/spitz.h index 0bfe6507c95d..25c9f62e46aa 100644 --- a/arch/arm/mach-pxa/include/mach/spitz.h +++ b/arch/arm/mach-pxa/include/mach/spitz.h @@ -15,8 +15,8 @@ #define __ASM_ARCH_SPITZ_H 1 #endif +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO, PXA_GPIO_TO_IRQ */ #include <linux/fb.h> -#include <linux/gpio.h> /* Spitz/Akita GPIOs */ diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h index 2bb0e862598c..0497d95cef25 100644 --- a/arch/arm/mach-pxa/include/mach/tosa.h +++ b/arch/arm/mach-pxa/include/mach/tosa.h @@ -13,6 +13,8 @@ #ifndef _ASM_ARCH_TOSA_H_ #define _ASM_ARCH_TOSA_H_ 1 +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ + /* TOSA Chip selects */ #define TOSA_LCDC_PHYS PXA_CS4_PHYS /* Internel Scoop */ diff --git a/arch/arm/mach-pxa/include/mach/trizeps4.h b/arch/arm/mach-pxa/include/mach/trizeps4.h index d2ca01053f69..ae3ca013afab 100644 --- a/arch/arm/mach-pxa/include/mach/trizeps4.h +++ b/arch/arm/mach-pxa/include/mach/trizeps4.h @@ -10,6 +10,8 @@ #ifndef _TRIPEPS4_H_ #define _TRIPEPS4_H_ +#include "irqs.h" /* PXA_GPIO_TO_IRQ */ + /* physical memory regions */ #define TRIZEPS4_FLASH_PHYS (PXA_CS0_PHYS) /* Flash region */ #define TRIZEPS4_DISK_PHYS (PXA_CS1_PHYS) /* Disk On Chip region */ diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig new file mode 100644 index 000000000000..a028be234334 --- /dev/null +++ b/arch/arm/mach-qcom/Kconfig @@ -0,0 +1,33 @@ +config ARCH_QCOM + bool "Qualcomm Support" if ARCH_MULTI_V7 + select ARCH_REQUIRE_GPIOLIB + select ARM_GIC + select CLKSRC_OF + select GENERIC_CLOCKEVENTS + select HAVE_SMP + select QCOM_SCM if SMP + help + Support for Qualcomm's devicetree based systems. + +if ARCH_QCOM + +menu "Qualcomm SoC Selection" + +config ARCH_MSM8X60 + bool "Enable support for MSM8X60" + select CLKSRC_QCOM + +config ARCH_MSM8960 + bool "Enable support for MSM8960" + select CLKSRC_QCOM + +config ARCH_MSM8974 + bool "Enable support for MSM8974" + select HAVE_ARM_ARCH_TIMER + +endmenu + +config QCOM_SCM + bool + +endif diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile new file mode 100644 index 000000000000..8f756ae1ae31 --- /dev/null +++ b/arch/arm/mach-qcom/Makefile @@ -0,0 +1,5 @@ +obj-y := board.o +obj-$(CONFIG_SMP) += platsmp.o +obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o + +CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-qcom/board.c index 1f11d93e700e..bae617ef0b31 100644 --- a/arch/arm/mach-msm/board-dt.c +++ b/arch/arm/mach-qcom/board.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -11,31 +11,16 @@ */ #include <linux/init.h> -#include <linux/of.h> -#include <linux/of_platform.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include "common.h" - -static const char * const msm_dt_match[] __initconst = { - "qcom,msm8660-fluid", +static const char * const qcom_dt_match[] __initconst = { "qcom,msm8660-surf", "qcom,msm8960-cdp", - NULL -}; - -static const char * const apq8074_dt_match[] __initconst = { "qcom,apq8074-dragonboard", NULL }; -DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") - .smp = smp_ops(msm_smp_ops), - .dt_compat = msm_dt_match, -MACHINE_END - -DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)") - .dt_compat = apq8074_dt_match, +DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)") + .dt_compat = qcom_dt_match, MACHINE_END diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c new file mode 100644 index 000000000000..d6908569ecaf --- /dev/null +++ b/arch/arm/mach-qcom/platsmp.c @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2002 ARM Ltd. + * All Rights Reserved + * Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/smp.h> +#include <linux/io.h> + +#include <asm/smp_plat.h> + +#include "scm-boot.h" + +#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0 +#define SCSS_CPU1CORE_RESET 0x2d80 +#define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64 + +#define APCS_CPU_PWR_CTL 0x04 +#define PLL_CLAMP BIT(8) +#define CORE_PWRD_UP BIT(7) +#define COREPOR_RST BIT(5) +#define CORE_RST BIT(4) +#define L2DT_SLP BIT(3) +#define CLAMP BIT(0) + +#define APC_PWR_GATE_CTL 0x14 +#define BHS_CNT_SHIFT 24 +#define LDO_PWR_DWN_SHIFT 16 +#define LDO_BYP_SHIFT 8 +#define BHS_SEG_SHIFT 1 +#define BHS_EN BIT(0) + +#define APCS_SAW2_VCTL 0x14 +#define APCS_SAW2_2_VCTL 0x1c + +extern void secondary_startup(void); + +static DEFINE_SPINLOCK(boot_lock); + +#ifdef CONFIG_HOTPLUG_CPU +static void __ref qcom_cpu_die(unsigned int cpu) +{ + wfi(); +} +#endif + +static void qcom_secondary_init(unsigned int cpu) +{ + /* + * Synchronise with the boot thread. + */ + spin_lock(&boot_lock); + spin_unlock(&boot_lock); +} + +static int scss_release_secondary(unsigned int cpu) +{ + struct device_node *node; + void __iomem *base; + + node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660"); + if (!node) { + pr_err("%s: can't find node\n", __func__); + return -ENXIO; + } + + base = of_iomap(node, 0); + of_node_put(node); + if (!base) + return -ENOMEM; + + writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL); + writel_relaxed(0, base + SCSS_CPU1CORE_RESET); + writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP); + mb(); + iounmap(base); + + return 0; +} + +static int kpssv1_release_secondary(unsigned int cpu) +{ + int ret = 0; + void __iomem *reg, *saw_reg; + struct device_node *cpu_node, *acc_node, *saw_node; + u32 val; + + cpu_node = of_get_cpu_node(cpu, NULL); + if (!cpu_node) + return -ENODEV; + + acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0); + if (!acc_node) { + ret = -ENODEV; + goto out_acc; + } + + saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0); + if (!saw_node) { + ret = -ENODEV; + goto out_saw; + } + + reg = of_iomap(acc_node, 0); + if (!reg) { + ret = -ENOMEM; + goto out_acc_map; + } + + saw_reg = of_iomap(saw_node, 0); + if (!saw_reg) { + ret = -ENOMEM; + goto out_saw_map; + } + + /* Turn on CPU rail */ + writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL); + mb(); + udelay(512); + + /* Krait bring-up sequence */ + val = PLL_CLAMP | L2DT_SLP | CLAMP; + writel_relaxed(val, reg + APCS_CPU_PWR_CTL); + val &= ~L2DT_SLP; + writel_relaxed(val, reg + APCS_CPU_PWR_CTL); + mb(); + ndelay(300); + + val |= COREPOR_RST; + writel_relaxed(val, reg + APCS_CPU_PWR_CTL); + mb(); + udelay(2); + + val &= ~CLAMP; + writel_relaxed(val, reg + APCS_CPU_PWR_CTL); + mb(); + udelay(2); + + val &= ~COREPOR_RST; + writel_relaxed(val, reg + APCS_CPU_PWR_CTL); + mb(); + udelay(100); + + val |= CORE_PWRD_UP; + writel_relaxed(val, reg + APCS_CPU_PWR_CTL); + mb(); + + iounmap(saw_reg); +out_saw_map: + iounmap(reg); +out_acc_map: + of_node_put(saw_node); +out_saw: + of_node_put(acc_node); +out_acc: + of_node_put(cpu_node); + return ret; +} + +static int kpssv2_release_secondary(unsigned int cpu) +{ + void __iomem *reg; + struct device_node *cpu_node, *l2_node, *acc_node, *saw_node; + void __iomem *l2_saw_base; + unsigned reg_val; + int ret; + + cpu_node = of_get_cpu_node(cpu, NULL); + if (!cpu_node) + return -ENODEV; + + acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0); + if (!acc_node) { + ret = -ENODEV; + goto out_acc; + } + + l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0); + if (!l2_node) { + ret = -ENODEV; + goto out_l2; + } + + saw_node = of_parse_phandle(l2_node, "qcom,saw", 0); + if (!saw_node) { + ret = -ENODEV; + goto out_saw; + } + + reg = of_iomap(acc_node, 0); + if (!reg) { + ret = -ENOMEM; + goto out_map; + } + + l2_saw_base = of_iomap(saw_node, 0); + if (!l2_saw_base) { + ret = -ENOMEM; + goto out_saw_map; + } + + /* Turn on the BHS, turn off LDO Bypass and power down LDO */ + reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN; + writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL); + mb(); + /* wait for the BHS to settle */ + udelay(1); + + /* Turn on BHS segments */ + reg_val |= 0x3f << BHS_SEG_SHIFT; + writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL); + mb(); + /* wait for the BHS to settle */ + udelay(1); + + /* Finally turn on the bypass so that BHS supplies power */ + reg_val |= 0x3f << LDO_BYP_SHIFT; + writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL); + + /* enable max phases */ + writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL); + mb(); + udelay(50); + + reg_val = COREPOR_RST | CLAMP; + writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL); + mb(); + udelay(2); + + reg_val &= ~CLAMP; + writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL); + mb(); + udelay(2); + + reg_val &= ~COREPOR_RST; + writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL); + mb(); + + reg_val |= CORE_PWRD_UP; + writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL); + mb(); + + ret = 0; + + iounmap(l2_saw_base); +out_saw_map: + iounmap(reg); +out_map: + of_node_put(saw_node); +out_saw: + of_node_put(l2_node); +out_l2: + of_node_put(acc_node); +out_acc: + of_node_put(cpu_node); + + return ret; +} + +static DEFINE_PER_CPU(int, cold_boot_done); + +static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int)) +{ + int ret = 0; + + if (!per_cpu(cold_boot_done, cpu)) { + ret = func(cpu); + if (!ret) + per_cpu(cold_boot_done, cpu) = true; + } + + /* + * set synchronisation state between this boot processor + * and the secondary one + */ + spin_lock(&boot_lock); + + /* + * Send the secondary CPU a soft interrupt, thereby causing + * the boot monitor to read the system wide flags register, + * and branch to the address found there. + */ + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + + /* + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + spin_unlock(&boot_lock); + + return ret; +} + +static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + return qcom_boot_secondary(cpu, scss_release_secondary); +} + +static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + return qcom_boot_secondary(cpu, kpssv1_release_secondary); +} + +static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + return qcom_boot_secondary(cpu, kpssv2_release_secondary); +} + +static void __init qcom_smp_prepare_cpus(unsigned int max_cpus) +{ + int cpu, map; + unsigned int flags = 0; + static const int cold_boot_flags[] = { + 0, + SCM_FLAG_COLDBOOT_CPU1, + SCM_FLAG_COLDBOOT_CPU2, + SCM_FLAG_COLDBOOT_CPU3, + }; + + for_each_present_cpu(cpu) { + map = cpu_logical_map(cpu); + if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) { + set_cpu_present(cpu, false); + continue; + } + flags |= cold_boot_flags[map]; + } + + if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) { + for_each_present_cpu(cpu) { + if (cpu == smp_processor_id()) + continue; + set_cpu_present(cpu, false); + } + pr_warn("Failed to set CPU boot address, disabling SMP\n"); + } +} + +static struct smp_operations smp_msm8660_ops __initdata = { + .smp_prepare_cpus = qcom_smp_prepare_cpus, + .smp_secondary_init = qcom_secondary_init, + .smp_boot_secondary = msm8660_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = qcom_cpu_die, +#endif +}; +CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops); + +static struct smp_operations qcom_smp_kpssv1_ops __initdata = { + .smp_prepare_cpus = qcom_smp_prepare_cpus, + .smp_secondary_init = qcom_secondary_init, + .smp_boot_secondary = kpssv1_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = qcom_cpu_die, +#endif +}; +CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops); + +static struct smp_operations qcom_smp_kpssv2_ops __initdata = { + .smp_prepare_cpus = qcom_smp_prepare_cpus, + .smp_secondary_init = qcom_secondary_init, + .smp_boot_secondary = kpssv2_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = qcom_cpu_die, +#endif +}; +CPU_METHOD_OF_DECLARE(qcom_smp_kpssv2, "qcom,kpss-acc-v2", &qcom_smp_kpssv2_ops); diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c index 45cee3e469a5..45cee3e469a5 100644 --- a/arch/arm/mach-msm/scm-boot.c +++ b/arch/arm/mach-qcom/scm-boot.c diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h index 7be32ff5d687..6aabb2428176 100644 --- a/arch/arm/mach-msm/scm-boot.h +++ b/arch/arm/mach-qcom/scm-boot.h @@ -13,9 +13,11 @@ #define __MACH_SCM_BOOT_H #define SCM_BOOT_ADDR 0x1 -#define SCM_FLAG_COLDBOOT_CPU1 0x1 -#define SCM_FLAG_WARMBOOT_CPU1 0x2 -#define SCM_FLAG_WARMBOOT_CPU0 0x4 +#define SCM_FLAG_COLDBOOT_CPU1 0x01 +#define SCM_FLAG_COLDBOOT_CPU2 0x08 +#define SCM_FLAG_COLDBOOT_CPU3 0x20 +#define SCM_FLAG_WARMBOOT_CPU0 0x04 +#define SCM_FLAG_WARMBOOT_CPU1 0x02 int scm_set_boot_addr(phys_addr_t addr, int flags); diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-qcom/scm.c index c536fd6bf827..c536fd6bf827 100644 --- a/arch/arm/mach-msm/scm.c +++ b/arch/arm/mach-qcom/scm.c diff --git a/arch/arm/mach-msm/scm.h b/arch/arm/mach-qcom/scm.h index 00b31ea58f29..00b31ea58f29 100644 --- a/arch/arm/mach-msm/scm.h +++ b/arch/arm/mach-qcom/scm.h diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index cf073dea5784..133410e178a7 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -5,6 +5,7 @@ config ARCH_ROCKCHIP select ARCH_REQUIRE_GPIOLIB select ARM_GIC select CACHE_L2X0 + select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP select HAVE_SMP select COMMON_CLK diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 1547d4fc920a..4377a1436a98 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o +obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/mach-rockchip/core.h b/arch/arm/mach-rockchip/core.h new file mode 100644 index 000000000000..e2e7c9dbb200 --- /dev/null +++ b/arch/arm/mach-rockchip/core.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +extern char rockchip_secondary_trampoline; +extern char rockchip_secondary_trampoline_end; + +extern unsigned long rockchip_boot_fn; +extern void rockchip_secondary_startup(void); + +extern struct smp_operations rockchip_smp_ops; diff --git a/arch/arm/mach-rockchip/headsmp.S b/arch/arm/mach-rockchip/headsmp.S new file mode 100644 index 000000000000..73206e360e31 --- /dev/null +++ b/arch/arm/mach-rockchip/headsmp.S @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <linux/linkage.h> +#include <linux/init.h> + +ENTRY(rockchip_secondary_startup) + bl v7_invalidate_l1 + b secondary_startup +ENDPROC(rockchip_secondary_startup) + +ENTRY(rockchip_secondary_trampoline) + ldr pc, 1f +ENDPROC(rockchip_secondary_trampoline) + .globl rockchip_boot_fn +rockchip_boot_fn: +1: .space 4 + +ENTRY(rockchip_secondary_trampoline_end) diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c new file mode 100644 index 000000000000..dbfa5a26cfff --- /dev/null +++ b/arch/arm/mach-rockchip/platsmp.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner <heiko@sntech.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <asm/cacheflush.h> +#include <asm/smp_scu.h> +#include <asm/smp_plat.h> +#include <asm/mach/map.h> + +#include "core.h" + +static void __iomem *scu_base_addr; +static void __iomem *sram_base_addr; +static int ncores; + +#define PMU_PWRDN_CON 0x08 +#define PMU_PWRDN_ST 0x0c + +#define PMU_PWRDN_SCU 4 + +static void __iomem *pmu_base_addr; + +static inline bool pmu_power_domain_is_on(int pd) +{ + return !(readl_relaxed(pmu_base_addr + PMU_PWRDN_ST) & BIT(pd)); +} + +static void pmu_set_power_domain(int pd, bool on) +{ + u32 val = readl_relaxed(pmu_base_addr + PMU_PWRDN_CON); + if (on) + val &= ~BIT(pd); + else + val |= BIT(pd); + writel(val, pmu_base_addr + PMU_PWRDN_CON); + + while (pmu_power_domain_is_on(pd) != on) { } +} + +/* + * Handling of CPU cores + */ + +static int __cpuinit rockchip_boot_secondary(unsigned int cpu, + struct task_struct *idle) +{ + if (!sram_base_addr || !pmu_base_addr) { + pr_err("%s: sram or pmu missing for cpu boot\n", __func__); + return -ENXIO; + } + + if (cpu >= ncores) { + pr_err("%s: cpu %d outside maximum number of cpus %d\n", + __func__, cpu, ncores); + return -ENXIO; + } + + /* start the core */ + pmu_set_power_domain(0 + cpu, true); + + return 0; +} + +/** + * rockchip_smp_prepare_sram - populate necessary sram block + * Starting cores execute the code residing at the start of the on-chip sram + * after power-on. Therefore make sure, this sram region is reserved and + * big enough. After this check, copy the trampoline code that directs the + * core to the real startup code in ram into the sram-region. + * @node: mmio-sram device node + */ +static int __init rockchip_smp_prepare_sram(struct device_node *node) +{ + unsigned int trampoline_sz = &rockchip_secondary_trampoline_end - + &rockchip_secondary_trampoline; + struct resource res; + unsigned int rsize; + int ret; + + ret = of_address_to_resource(node, 0, &res); + if (ret < 0) { + pr_err("%s: could not get address for node %s\n", + __func__, node->full_name); + return ret; + } + + rsize = resource_size(&res); + if (rsize < trampoline_sz) { + pr_err("%s: reserved block with size 0x%x is to small for trampoline size 0x%x\n", + __func__, rsize, trampoline_sz); + return -EINVAL; + } + + sram_base_addr = of_iomap(node, 0); + + /* set the boot function for the sram code */ + rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup); + + /* copy the trampoline to sram, that runs during startup of the core */ + memcpy(sram_base_addr, &rockchip_secondary_trampoline, trampoline_sz); + flush_cache_all(); + outer_clean_range(0, trampoline_sz); + + dsb_sev(); + + return 0; +} + +static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) +{ + struct device_node *node; + unsigned int i; + + node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); + if (!node) { + pr_err("%s: missing scu\n", __func__); + return; + } + + scu_base_addr = of_iomap(node, 0); + if (!scu_base_addr) { + pr_err("%s: could not map scu registers\n", __func__); + return; + } + + node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-smp-sram"); + if (!node) { + pr_err("%s: could not find sram dt node\n", __func__); + return; + } + + if (rockchip_smp_prepare_sram(node)) + return; + + node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); + if (!node) { + pr_err("%s: could not find sram dt node\n", __func__); + return; + } + + pmu_base_addr = of_iomap(node, 0); + if (!pmu_base_addr) { + pr_err("%s: could not map pmu registers\n", __func__); + return; + } + + /* enable the SCU power domain */ + pmu_set_power_domain(PMU_PWRDN_SCU, true); + + /* + * While the number of cpus is gathered from dt, also get the number + * of cores from the scu to verify this value when booting the cores. + */ + ncores = scu_get_core_count(scu_base_addr); + + scu_enable(scu_base_addr); + + /* Make sure that all cores except the first are really off */ + for (i = 1; i < ncores; i++) + pmu_set_power_domain(0 + i, false); +} + +struct smp_operations rockchip_smp_ops __initdata = { + .smp_prepare_cpus = rockchip_smp_prepare_cpus, + .smp_boot_secondary = rockchip_boot_secondary, +}; diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index 82c0b0709712..d211d6fa0d98 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -22,6 +22,7 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/hardware/cache-l2x0.h> +#include "core.h" static void __init rockchip_dt_init(void) { @@ -38,6 +39,7 @@ static const char * const rockchip_board_dt_compat[] = { }; DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)") + .smp = smp_ops(rockchip_smp_ops), .init_machine = rockchip_dt_init, .dt_compat = rockchip_board_dt_compat, MACHINE_END diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 338640631e08..05fa505df585 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -8,7 +8,7 @@ config ARCH_SHMOBILE_MULTI select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP - select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_ARM_TWD if SMP select HAVE_SMP select ARM_GIC select MIGHT_HAVE_CACHE_L2X0 diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 1db2a5ca9ab8..8c09a8393fb6 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -25,6 +25,7 @@ #include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/of.h> +#include <linux/memblock.h> #include <linux/irqchip.h> #include <linux/irqchip/arm-gic.h> @@ -41,6 +42,18 @@ void __iomem *zynq_scu_base; +/** + * zynq_memory_init - Initialize special memory + * + * We need to stop things allocating the low memory as DMA can't work in + * the 1st 512K of memory. + */ +static void __init zynq_memory_init(void) +{ + if (!__pa(PAGE_OFFSET)) + memblock_reserve(__pa(PAGE_OFFSET), __pa(swapper_pg_dir)); +} + static struct platform_device zynq_cpuidle_device = { .name = "cpuidle-zynq", }; @@ -117,5 +130,6 @@ DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") .init_machine = zynq_init_machine, .init_time = zynq_timer_init, .dt_compat = zynq_dt_match, + .reserve = zynq_memory_init, .restart = zynq_system_reset, MACHINE_END |