aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/cpus.txt25
-rw-r--r--Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt30
-rw-r--r--Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt35
-rw-r--r--MAINTAINERS8
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/dts/Makefile6
-rw-r--r--arch/arm/boot/dts/qcom-msm8660-surf.dts59
-rw-r--r--arch/arm/boot/dts/qcom-msm8660.dtsi63
-rw-r--r--arch/arm/boot/dts/qcom-msm8960-cdp.dts66
-rw-r--r--arch/arm/boot/dts/qcom-msm8960.dtsi70
-rw-r--r--arch/arm/include/asm/smp.h9
-rw-r--r--arch/arm/kernel/devtree.c40
-rw-r--r--arch/arm/mach-msm/Kconfig54
-rw-r--r--arch/arm/mach-msm/Makefile8
-rw-r--r--arch/arm/mach-msm/common.h3
-rw-r--r--arch/arm/mach-msm/headsmp.S39
-rw-r--r--arch/arm/mach-msm/hotplug.c74
-rw-r--r--arch/arm/mach-msm/platsmp.c161
-rw-r--r--arch/arm/mach-qcom/Kconfig33
-rw-r--r--arch/arm/mach-qcom/Makefile5
-rw-r--r--arch/arm/mach-qcom/board.c (renamed from arch/arm/mach-msm/board-dt.c)23
-rw-r--r--arch/arm/mach-qcom/platsmp.c378
-rw-r--r--arch/arm/mach-qcom/scm-boot.c (renamed from arch/arm/mach-msm/scm-boot.c)0
-rw-r--r--arch/arm/mach-qcom/scm-boot.h (renamed from arch/arm/mach-msm/scm-boot.h)8
-rw-r--r--arch/arm/mach-qcom/scm.c (renamed from arch/arm/mach-msm/scm.c)0
-rw-r--r--arch/arm/mach-qcom/scm.h (renamed from arch/arm/mach-msm/scm.h)0
-rw-r--r--drivers/clocksource/Kconfig3
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/qcom-timer.c (renamed from arch/arm/mach-msm/timer.c)29
-rw-r--r--include/asm-generic/vmlinux.lds.h10
32 files changed, 747 insertions, 503 deletions
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 91304353eea4..333f4aea3029 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -180,7 +180,11 @@ nodes to be present and contain the properties described below.
180 be one of: 180 be one of:
181 "spin-table" 181 "spin-table"
182 "psci" 182 "psci"
183 # On ARM 32-bit systems this property is optional. 183 # On ARM 32-bit systems this property is optional and
184 can be one of:
185 "qcom,gcc-msm8660"
186 "qcom,kpss-acc-v1"
187 "qcom,kpss-acc-v2"
184 188
185 - cpu-release-addr 189 - cpu-release-addr
186 Usage: required for systems that have an "enable-method" 190 Usage: required for systems that have an "enable-method"
@@ -191,6 +195,21 @@ nodes to be present and contain the properties described below.
191 property identifying a 64-bit zero-initialised 195 property identifying a 64-bit zero-initialised
192 memory location. 196 memory location.
193 197
198 - qcom,saw
199 Usage: required for systems that have an "enable-method"
200 property value of "qcom,kpss-acc-v1" or
201 "qcom,kpss-acc-v2"
202 Value type: <phandle>
203 Definition: Specifies the SAW[1] node associated with this CPU.
204
205 - qcom,acc
206 Usage: required for systems that have an "enable-method"
207 property value of "qcom,kpss-acc-v1" or
208 "qcom,kpss-acc-v2"
209 Value type: <phandle>
210 Definition: Specifies the ACC[2] node associated with this CPU.
211
212
194Example 1 (dual-cluster big.LITTLE system 32-bit): 213Example 1 (dual-cluster big.LITTLE system 32-bit):
195 214
196 cpus { 215 cpus {
@@ -382,3 +401,7 @@ cpus {
382 cpu-release-addr = <0 0x20000000>; 401 cpu-release-addr = <0 0x20000000>;
383 }; 402 };
384}; 403};
404
405--
406[1] arm/msm/qcom,saw2.txt
407[2] arm/msm/qcom,kpss-acc.txt
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
new file mode 100644
index 000000000000..1333db9acfee
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
@@ -0,0 +1,30 @@
1Krait Processor Sub-system (KPSS) Application Clock Controller (ACC)
2
3The KPSS ACC provides clock, power domain, and reset control to a Krait CPU.
4There is one ACC register region per CPU within the KPSS remapped region as
5well as an alias register region that remaps accesses to the ACC associated
6with the CPU accessing the region.
7
8PROPERTIES
9
10- compatible:
11 Usage: required
12 Value type: <string>
13 Definition: should be one of:
14 "qcom,kpss-acc-v1"
15 "qcom,kpss-acc-v2"
16
17- reg:
18 Usage: required
19 Value type: <prop-encoded-array>
20 Definition: the first element specifies the base address and size of
21 the register region. An optional second element specifies
22 the base address and size of the alias register region.
23
24Example:
25
26 clock-controller@2088000 {
27 compatible = "qcom,kpss-acc-v2";
28 reg = <0x02088000 0x1000>,
29 <0x02008000 0x1000>;
30 };
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
new file mode 100644
index 000000000000..1505fb8e131a
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
@@ -0,0 +1,35 @@
1SPM AVS Wrapper 2 (SAW2)
2
3The SAW2 is a wrapper around the Subsystem Power Manager (SPM) and the
4Adaptive Voltage Scaling (AVS) hardware. The SPM is a programmable
5micro-controller that transitions a piece of hardware (like a processor or
6subsystem) into and out of low power modes via a direct connection to
7the PMIC. It can also be wired up to interact with other processors in the
8system, notifying them when a low power state is entered or exited.
9
10PROPERTIES
11
12- compatible:
13 Usage: required
14 Value type: <string>
15 Definition: shall contain "qcom,saw2". A more specific value should be
16 one of:
17 "qcom,saw2-v1"
18 "qcom,saw2-v1.1"
19 "qcom,saw2-v2"
20 "qcom,saw2-v2.1"
21
22- reg:
23 Usage: required
24 Value type: <prop-encoded-array>
25 Definition: the first element specifies the base address and size of
26 the register region. An optional second element specifies
27 the base address and size of the alias register region.
28
29
30Example:
31
32 regulator@2099000 {
33 compatible = "qcom,saw2";
34 reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
35 };
diff --git a/MAINTAINERS b/MAINTAINERS
index fb08dcececf1..9dbf7f1898c5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1167,6 +1167,14 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
1167W: http://www.arm.linux.org.uk/ 1167W: http://www.arm.linux.org.uk/
1168S: Maintained 1168S: Maintained
1169 1169
1170ARM/QUALCOMM SUPPORT
1171M: Kumar Gala <galak@codeaurora.org>
1172M: David Brown <davidb@codeaurora.org>
1173L: linux-arm-msm@vger.kernel.org
1174S: Maintained
1175F: arch/arm/mach-qcom/
1176T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
1177
1170ARM/RADISYS ENP2611 MACHINE SUPPORT 1178ARM/RADISYS ENP2611 MACHINE SUPPORT
1171M: Lennert Buytenhek <kernel@wantstofly.org> 1179M: Lennert Buytenhek <kernel@wantstofly.org>
1172L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 1180L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e25419817791..f093f2030c1c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -657,9 +657,8 @@ config ARCH_PXA
657 help 657 help
658 Support for Intel/Marvell's PXA2xx/PXA3xx processor line. 658 Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
659 659
660config ARCH_MSM_NODT 660config ARCH_MSM
661 bool "Qualcomm MSM" 661 bool "Qualcomm MSM (non-multiplatform)"
662 select ARCH_MSM
663 select ARCH_REQUIRE_GPIOLIB 662 select ARCH_REQUIRE_GPIOLIB
664 select COMMON_CLK 663 select COMMON_CLK
665 select GENERIC_CLOCKEVENTS 664 select GENERIC_CLOCKEVENTS
@@ -1005,6 +1004,8 @@ source "arch/arm/plat-pxa/Kconfig"
1005 1004
1006source "arch/arm/mach-mmp/Kconfig" 1005source "arch/arm/mach-mmp/Kconfig"
1007 1006
1007source "arch/arm/mach-qcom/Kconfig"
1008
1008source "arch/arm/mach-realview/Kconfig" 1009source "arch/arm/mach-realview/Kconfig"
1009 1010
1010source "arch/arm/mach-rockchip/Kconfig" 1011source "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
956 956
957config DEBUG_MSM_UART 957config DEBUG_MSM_UART
958 bool 958 bool
959 depends on ARCH_MSM 959 depends on ARCH_MSM || ARCH_QCOM
960 960
961config DEBUG_LL_INCLUDE 961config DEBUG_LL_INCLUDE
962 string 962 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
180machine-$(CONFIG_ARCH_ORION5X) += orion5x 180machine-$(CONFIG_ARCH_ORION5X) += orion5x
181machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell 181machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell
182machine-$(CONFIG_ARCH_PXA) += pxa 182machine-$(CONFIG_ARCH_PXA) += pxa
183machine-$(CONFIG_ARCH_QCOM) += qcom
183machine-$(CONFIG_ARCH_REALVIEW) += realview 184machine-$(CONFIG_ARCH_REALVIEW) += realview
184machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip 185machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip
185machine-$(CONFIG_ARCH_RPC) += rpc 186machine-$(CONFIG_ARCH_RPC) += rpc
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 6d1e43d46187..3269029a1ce6 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -119,9 +119,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
119 kirkwood-ts219-6282.dtb 119 kirkwood-ts219-6282.dtb
120dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb 120dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
121dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb 121dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
122dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
123 qcom-msm8960-cdp.dtb \
124 qcom-apq8074-dragonboard.dtb
125dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ 122dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
126 armada-370-mirabox.dtb \ 123 armada-370-mirabox.dtb \
127 armada-370-netgear-rn102.dtb \ 124 armada-370-netgear-rn102.dtb \
@@ -233,6 +230,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
233 dra7-evm.dtb 230 dra7-evm.dtb
234dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb 231dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
235dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb 232dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
233dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
234 qcom-msm8960-cdp.dtb \
235 qcom-apq8074-dragonboard.dtb
236dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ 236dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
237 ste-hrefprev60-stuib.dtb \ 237 ste-hrefprev60-stuib.dtb \
238 ste-hrefprev60-tvk.dtb \ 238 ste-hrefprev60-tvk.dtb \
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 @@
1/dts-v1/; 1#include "qcom-msm8660.dtsi"
2
3/include/ "skeleton.dtsi"
4
5#include <dt-bindings/clock/qcom,gcc-msm8660.h>
6 2
7/ { 3/ {
8 model = "Qualcomm MSM8660 SURF"; 4 model = "Qualcomm MSM8660 SURF";
9 compatible = "qcom,msm8660-surf", "qcom,msm8660"; 5 compatible = "qcom,msm8660-surf", "qcom,msm8660";
10 interrupt-parent = <&intc>;
11
12 intc: interrupt-controller@2080000 {
13 compatible = "qcom,msm-8660-qgic";
14 interrupt-controller;
15 #interrupt-cells = <3>;
16 reg = < 0x02080000 0x1000 >,
17 < 0x02081000 0x1000 >;
18 };
19
20 timer@2000000 {
21 compatible = "qcom,scss-timer", "qcom,msm-timer";
22 interrupts = <1 0 0x301>,
23 <1 1 0x301>,
24 <1 2 0x301>;
25 reg = <0x02000000 0x100>;
26 clock-frequency = <27000000>,
27 <32768>;
28 cpu-offset = <0x40000>;
29 };
30
31 msmgpio: gpio@800000 {
32 compatible = "qcom,msm-gpio";
33 reg = <0x00800000 0x4000>;
34 gpio-controller;
35 #gpio-cells = <2>;
36 ngpio = <173>;
37 interrupts = <0 16 0x4>;
38 interrupt-controller;
39 #interrupt-cells = <2>;
40 };
41
42 gcc: clock-controller@900000 {
43 compatible = "qcom,gcc-msm8660";
44 #clock-cells = <1>;
45 #reset-cells = <1>;
46 reg = <0x900000 0x4000>;
47 };
48
49 serial@19c40000 {
50 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
51 reg = <0x19c40000 0x1000>,
52 <0x19c00000 0x1000>;
53 interrupts = <0 195 0x0>;
54 clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
55 clock-names = "core", "iface";
56 };
57
58 qcom,ssbi@500000 {
59 compatible = "qcom,ssbi";
60 reg = <0x500000 0x1000>;
61 qcom,controller-type = "pmic-arbiter";
62 };
63}; 6};
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 @@
1/dts-v1/;
2
3/include/ "skeleton.dtsi"
4
5#include <dt-bindings/clock/qcom,gcc-msm8660.h>
6
7/ {
8 model = "Qualcomm MSM8660";
9 compatible = "qcom,msm8660";
10 interrupt-parent = <&intc>;
11
12 intc: interrupt-controller@2080000 {
13 compatible = "qcom,msm-8660-qgic";
14 interrupt-controller;
15 #interrupt-cells = <3>;
16 reg = < 0x02080000 0x1000 >,
17 < 0x02081000 0x1000 >;
18 };
19
20 timer@2000000 {
21 compatible = "qcom,scss-timer", "qcom,msm-timer";
22 interrupts = <1 0 0x301>,
23 <1 1 0x301>,
24 <1 2 0x301>;
25 reg = <0x02000000 0x100>;
26 clock-frequency = <27000000>,
27 <32768>;
28 cpu-offset = <0x40000>;
29 };
30
31 msmgpio: gpio@800000 {
32 compatible = "qcom,msm-gpio";
33 reg = <0x00800000 0x4000>;
34 gpio-controller;
35 #gpio-cells = <2>;
36 ngpio = <173>;
37 interrupts = <0 16 0x4>;
38 interrupt-controller;
39 #interrupt-cells = <2>;
40 };
41
42 gcc: clock-controller@900000 {
43 compatible = "qcom,gcc-msm8660";
44 #clock-cells = <1>;
45 #reset-cells = <1>;
46 reg = <0x900000 0x4000>;
47 };
48
49 serial@19c40000 {
50 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
51 reg = <0x19c40000 0x1000>,
52 <0x19c00000 0x1000>;
53 interrupts = <0 195 0x0>;
54 clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
55 clock-names = "core", "iface";
56 };
57
58 qcom,ssbi@500000 {
59 compatible = "qcom,ssbi";
60 reg = <0x500000 0x1000>;
61 qcom,controller-type = "pmic-arbiter";
62 };
63};
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 @@
1/dts-v1/; 1#include "qcom-msm8960.dtsi"
2
3/include/ "skeleton.dtsi"
4
5#include <dt-bindings/clock/qcom,gcc-msm8960.h>
6 2
7/ { 3/ {
8 model = "Qualcomm MSM8960 CDP"; 4 model = "Qualcomm MSM8960 CDP";
9 compatible = "qcom,msm8960-cdp", "qcom,msm8960"; 5 compatible = "qcom,msm8960-cdp", "qcom,msm8960";
10 interrupt-parent = <&intc>;
11
12 intc: interrupt-controller@2000000 {
13 compatible = "qcom,msm-qgic2";
14 interrupt-controller;
15 #interrupt-cells = <3>;
16 reg = < 0x02000000 0x1000 >,
17 < 0x02002000 0x1000 >;
18 };
19
20 timer@200a000 {
21 compatible = "qcom,kpss-timer", "qcom,msm-timer";
22 interrupts = <1 1 0x301>,
23 <1 2 0x301>,
24 <1 3 0x301>;
25 reg = <0x0200a000 0x100>;
26 clock-frequency = <27000000>,
27 <32768>;
28 cpu-offset = <0x80000>;
29 };
30
31 msmgpio: gpio@800000 {
32 compatible = "qcom,msm-gpio";
33 gpio-controller;
34 #gpio-cells = <2>;
35 ngpio = <150>;
36 interrupts = <0 16 0x4>;
37 interrupt-controller;
38 #interrupt-cells = <2>;
39 reg = <0x800000 0x4000>;
40 };
41
42 gcc: clock-controller@900000 {
43 compatible = "qcom,gcc-msm8960";
44 #clock-cells = <1>;
45 #reset-cells = <1>;
46 reg = <0x900000 0x4000>;
47 };
48
49 clock-controller@4000000 {
50 compatible = "qcom,mmcc-msm8960";
51 reg = <0x4000000 0x1000>;
52 #clock-cells = <1>;
53 #reset-cells = <1>;
54 };
55
56 serial@16440000 {
57 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
58 reg = <0x16440000 0x1000>,
59 <0x16400000 0x1000>;
60 interrupts = <0 154 0x0>;
61 clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
62 clock-names = "core", "iface";
63 };
64
65 qcom,ssbi@500000 {
66 compatible = "qcom,ssbi";
67 reg = <0x500000 0x1000>;
68 qcom,controller-type = "pmic-arbiter";
69 };
70}; 6};
diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
new file mode 100644
index 000000000000..ff002826552a
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
@@ -0,0 +1,70 @@
1/dts-v1/;
2
3/include/ "skeleton.dtsi"
4
5#include <dt-bindings/clock/qcom,gcc-msm8960.h>
6
7/ {
8 model = "Qualcomm MSM8960";
9 compatible = "qcom,msm8960";
10 interrupt-parent = <&intc>;
11
12 intc: interrupt-controller@2000000 {
13 compatible = "qcom,msm-qgic2";
14 interrupt-controller;
15 #interrupt-cells = <3>;
16 reg = < 0x02000000 0x1000 >,
17 < 0x02002000 0x1000 >;
18 };
19
20 timer@200a000 {
21 compatible = "qcom,kpss-timer", "qcom,msm-timer";
22 interrupts = <1 1 0x301>,
23 <1 2 0x301>,
24 <1 3 0x301>;
25 reg = <0x0200a000 0x100>;
26 clock-frequency = <27000000>,
27 <32768>;
28 cpu-offset = <0x80000>;
29 };
30
31 msmgpio: gpio@800000 {
32 compatible = "qcom,msm-gpio";
33 gpio-controller;
34 #gpio-cells = <2>;
35 ngpio = <150>;
36 interrupts = <0 16 0x4>;
37 interrupt-controller;
38 #interrupt-cells = <2>;
39 reg = <0x800000 0x4000>;
40 };
41
42 gcc: clock-controller@900000 {
43 compatible = "qcom,gcc-msm8960";
44 #clock-cells = <1>;
45 #reset-cells = <1>;
46 reg = <0x900000 0x4000>;
47 };
48
49 clock-controller@4000000 {
50 compatible = "qcom,mmcc-msm8960";
51 reg = <0x4000000 0x1000>;
52 #clock-cells = <1>;
53 #reset-cells = <1>;
54 };
55
56 serial@16440000 {
57 compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
58 reg = <0x16440000 0x1000>,
59 <0x16400000 0x1000>;
60 interrupts = <0 154 0x0>;
61 clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
62 clock-names = "core", "iface";
63 };
64
65 qcom,ssbi@500000 {
66 compatible = "qcom,ssbi";
67 reg = <0x500000 0x1000>;
68 qcom,controller-type = "pmic-arbiter";
69 };
70};
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 {
114#endif 114#endif
115}; 115};
116 116
117struct of_cpu_method {
118 const char *method;
119 struct smp_operations *ops;
120};
121
122#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \
123 static const struct of_cpu_method __cpu_method_of_table_##name \
124 __used __section(__cpu_method_of_table) \
125 = { .method = _method, .ops = _ops }
117/* 126/*
118 * set platform specific SMP operations 127 * set platform specific SMP operations
119 */ 128 */
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 @@
18#include <linux/of_fdt.h> 18#include <linux/of_fdt.h>
19#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/of_platform.h> 20#include <linux/of_platform.h>
21#include <linux/smp.h>
21 22
22#include <asm/cputype.h> 23#include <asm/cputype.h>
23#include <asm/setup.h> 24#include <asm/setup.h>
@@ -63,6 +64,34 @@ void __init arm_dt_memblock_reserve(void)
63 } 64 }
64} 65}
65 66
67#ifdef CONFIG_SMP
68extern struct of_cpu_method __cpu_method_of_table_begin[];
69extern struct of_cpu_method __cpu_method_of_table_end[];
70
71static int __init set_smp_ops_by_method(struct device_node *node)
72{
73 const char *method;
74 struct of_cpu_method *m = __cpu_method_of_table_begin;
75
76 if (of_property_read_string(node, "enable-method", &method))
77 return 0;
78
79 for (; m < __cpu_method_of_table_end; m++)
80 if (!strcmp(m->method, method)) {
81 smp_set_ops(m->ops);
82 return 1;
83 }
84
85 return 0;
86}
87#else
88static inline int set_smp_ops_by_method(struct device_node *node)
89{
90 return 1;
91}
92#endif
93
94
66/* 95/*
67 * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree 96 * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
68 * and builds the cpu logical map array containing MPIDR values related to 97 * and builds the cpu logical map array containing MPIDR values related to
@@ -79,6 +108,7 @@ void __init arm_dt_init_cpu_maps(void)
79 * read as 0. 108 * read as 0.
80 */ 109 */
81 struct device_node *cpu, *cpus; 110 struct device_node *cpu, *cpus;
111 int found_method = 0;
82 u32 i, j, cpuidx = 1; 112 u32 i, j, cpuidx = 1;
83 u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; 113 u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
84 114
@@ -150,8 +180,18 @@ void __init arm_dt_init_cpu_maps(void)
150 } 180 }
151 181
152 tmp_map[i] = hwid; 182 tmp_map[i] = hwid;
183
184 if (!found_method)
185 found_method = set_smp_ops_by_method(cpu);
153 } 186 }
154 187
188 /*
189 * Fallback to an enable-method in the cpus node if nothing found in
190 * a cpu node.
191 */
192 if (!found_method)
193 set_smp_ops_by_method(cpus);
194
155 if (!bootcpu_valid) { 195 if (!bootcpu_valid) {
156 pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n"); 196 pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n");
157 return; 197 return;
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 @@
1config ARCH_MSM
2 bool
3
4config ARCH_MSM_DT
5 bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7
6 select ARCH_MSM
7 select ARCH_REQUIRE_GPIOLIB
8 select CLKSRC_OF
9 select GENERIC_CLOCKEVENTS
10 help
11 Support for Qualcomm's devicetree based MSM systems.
12
13if ARCH_MSM 1if ARCH_MSM
14 2
15menu "Qualcomm MSM SoC Selection"
16 depends on ARCH_MSM_DT
17
18config ARCH_MSM8X60
19 bool "Enable support for MSM8X60"
20 select ARM_GIC
21 select CPU_V7
22 select HAVE_SMP
23 select MSM_SCM if SMP
24 select MSM_TIMER
25
26config ARCH_MSM8960
27 bool "Enable support for MSM8960"
28 select ARM_GIC
29 select CPU_V7
30 select HAVE_SMP
31 select MSM_SCM if SMP
32 select MSM_TIMER
33
34config ARCH_MSM8974
35 bool "Enable support for MSM8974"
36 select ARM_GIC
37 select CPU_V7
38 select HAVE_ARM_ARCH_TIMER
39 select HAVE_SMP
40 select MSM_SCM if SMP
41
42endmenu
43
44choice 3choice
45 prompt "Qualcomm MSM SoC Type" 4 prompt "Qualcomm MSM SoC Type"
46 default ARCH_MSM7X00A 5 default ARCH_MSM7X00A
47 depends on ARCH_MSM_NODT 6 depends on ARCH_MSM
48 7
49config ARCH_MSM7X00A 8config ARCH_MSM7X00A
50 bool "MSM7x00A / MSM7x01A" 9 bool "MSM7x00A / MSM7x01A"
@@ -54,7 +13,7 @@ config ARCH_MSM7X00A
54 select MACH_TROUT if !MACH_HALIBUT 13 select MACH_TROUT if !MACH_HALIBUT
55 select MSM_PROC_COMM 14 select MSM_PROC_COMM
56 select MSM_SMD 15 select MSM_SMD
57 select MSM_TIMER 16 select CLKSRC_QCOM
58 select MSM_SMD_PKG3 17 select MSM_SMD_PKG3
59 18
60config ARCH_MSM7X30 19config ARCH_MSM7X30
@@ -66,7 +25,7 @@ config ARCH_MSM7X30
66 select MSM_GPIOMUX 25 select MSM_GPIOMUX
67 select MSM_PROC_COMM 26 select MSM_PROC_COMM
68 select MSM_SMD 27 select MSM_SMD
69 select MSM_TIMER 28 select CLKSRC_QCOM
70 select MSM_VIC 29 select MSM_VIC
71 30
72config ARCH_QSD8X50 31config ARCH_QSD8X50
@@ -78,7 +37,7 @@ config ARCH_QSD8X50
78 select MSM_GPIOMUX 37 select MSM_GPIOMUX
79 select MSM_PROC_COMM 38 select MSM_PROC_COMM
80 select MSM_SMD 39 select MSM_SMD
81 select MSM_TIMER 40 select CLKSRC_QCOM
82 select MSM_VIC 41 select MSM_VIC
83 42
84endchoice 43endchoice
@@ -99,7 +58,7 @@ config MSM_VIC
99 bool 58 bool
100 59
101menu "Qualcomm MSM Board Type" 60menu "Qualcomm MSM Board Type"
102 depends on ARCH_MSM_NODT 61 depends on ARCH_MSM
103 62
104config MACH_HALIBUT 63config MACH_HALIBUT
105 depends on ARCH_MSM 64 depends on ARCH_MSM
@@ -153,7 +112,4 @@ config MSM_GPIOMUX
153config MSM_SCM 112config MSM_SCM
154 bool 113 bool
155 114
156config MSM_TIMER
157 bool
158
159endif 115endif
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 @@
1obj-$(CONFIG_MSM_TIMER) += timer.o
2obj-$(CONFIG_MSM_PROC_COMM) += clock.o 1obj-$(CONFIG_MSM_PROC_COMM) += clock.o
3 2
4obj-$(CONFIG_MSM_VIC) += irq-vic.o 3obj-$(CONFIG_MSM_VIC) += irq-vic.o
@@ -14,18 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
14 13
15obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o 14obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
16obj-$(CONFIG_MSM_SMD) += last_radio_log.o 15obj-$(CONFIG_MSM_SMD) += last_radio_log.o
17obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
18
19CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
20
21obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
22obj-$(CONFIG_SMP) += headsmp.o platsmp.o
23 16
24obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o 17obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
25obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o 18obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
26obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o 19obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
27obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o 20obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
28obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o 21obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
29obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
30obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o 22obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
31obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o 23obj-$(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);
23extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size, 23extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
24 unsigned int mtype, void *caller); 24 unsigned int mtype, void *caller);
25 25
26extern struct smp_operations msm_smp_ops;
27extern void msm_cpu_die(unsigned int cpu);
28
29struct msm_mmc_platform_data; 26struct msm_mmc_platform_data;
30 27
31extern void msm_add_devices(void); 28extern 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 @@
1/*
2 * linux/arch/arm/mach-realview/headsmp.S
3 *
4 * Copyright (c) 2003 ARM Limited
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/linkage.h>
12#include <linux/init.h>
13
14/*
15 * MSM specific entry point for secondary CPUs. This provides
16 * a "holding pen" into which all secondary cores are held until we're
17 * ready for them to initialise.
18 */
19ENTRY(msm_secondary_startup)
20 mrc p15, 0, r0, c0, c0, 5
21 and r0, r0, #15
22 adr r4, 1f
23 ldmia r4, {r5, r6}
24 sub r4, r4, r5
25 add r6, r6, r4
26pen: ldr r7, [r6]
27 cmp r7, r0
28 bne pen
29
30 /*
31 * we've been released from the holding pen: secondary_stack
32 * should now contain the SVC stack for this core
33 */
34 b secondary_startup
35ENDPROC(msm_secondary_startup)
36
37 .align
381: .long .
39 .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 @@
1/*
2 * Copyright (C) 2002 ARM Ltd.
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/kernel.h>
10#include <linux/errno.h>
11#include <linux/smp.h>
12
13#include <asm/smp_plat.h>
14
15#include "common.h"
16
17static inline void cpu_enter_lowpower(void)
18{
19}
20
21static inline void cpu_leave_lowpower(void)
22{
23}
24
25static inline void platform_do_lowpower(unsigned int cpu)
26{
27 /* Just enter wfi for now. TODO: Properly shut off the cpu. */
28 for (;;) {
29 /*
30 * here's the WFI
31 */
32 asm("wfi"
33 :
34 :
35 : "memory", "cc");
36
37 if (pen_release == cpu_logical_map(cpu)) {
38 /*
39 * OK, proper wakeup, we're done
40 */
41 break;
42 }
43
44 /*
45 * getting here, means that we have come out of WFI without
46 * having been woken up - this shouldn't happen
47 *
48 * The trouble is, letting people know about this is not really
49 * possible, since we are currently running incoherently, and
50 * therefore cannot safely call printk() or anything else
51 */
52 pr_debug("CPU%u: spurious wakeup call\n", cpu);
53 }
54}
55
56/*
57 * platform-specific code to shutdown a CPU
58 *
59 * Called with IRQs disabled
60 */
61void __ref msm_cpu_die(unsigned int cpu)
62{
63 /*
64 * we're ready for shutdown now, so do it
65 */
66 cpu_enter_lowpower();
67 platform_do_lowpower(cpu);
68
69 /*
70 * bring this CPU back into the world of cache
71 * coherency, and then restore interrupts
72 */
73 cpu_leave_lowpower();
74}
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 @@
1/*
2 * Copyright (C) 2002 ARM Ltd.
3 * All Rights Reserved
4 * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/init.h>
12#include <linux/errno.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/jiffies.h>
16#include <linux/smp.h>
17#include <linux/io.h>
18
19#include <asm/cacheflush.h>
20#include <asm/cputype.h>
21#include <asm/mach-types.h>
22#include <asm/smp_plat.h>
23
24#include "scm-boot.h"
25#include "common.h"
26
27#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
28#define SCSS_CPU1CORE_RESET 0xD80
29#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
30
31extern void msm_secondary_startup(void);
32
33static DEFINE_SPINLOCK(boot_lock);
34
35static inline int get_core_count(void)
36{
37 /* 1 + the PART[1:0] field of MIDR */
38 return ((read_cpuid_id() >> 4) & 3) + 1;
39}
40
41static void msm_secondary_init(unsigned int cpu)
42{
43 /*
44 * let the primary processor know we're out of the
45 * pen, then head off into the C entry point
46 */
47 pen_release = -1;
48 smp_wmb();
49
50 /*
51 * Synchronise with the boot thread.
52 */
53 spin_lock(&boot_lock);
54 spin_unlock(&boot_lock);
55}
56
57static void prepare_cold_cpu(unsigned int cpu)
58{
59 int ret;
60 ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
61 SCM_FLAG_COLDBOOT_CPU1);
62 if (ret == 0) {
63 void __iomem *sc1_base_ptr;
64 sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
65 if (sc1_base_ptr) {
66 writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
67 writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
68 writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
69 iounmap(sc1_base_ptr);
70 }
71 } else
72 printk(KERN_DEBUG "Failed to set secondary core boot "
73 "address\n");
74}
75
76static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
77{
78 unsigned long timeout;
79 static int cold_boot_done;
80
81 /* Only need to bring cpu out of reset this way once */
82 if (cold_boot_done == false) {
83 prepare_cold_cpu(cpu);
84 cold_boot_done = true;
85 }
86
87 /*
88 * set synchronisation state between this boot processor
89 * and the secondary one
90 */
91 spin_lock(&boot_lock);
92
93 /*
94 * The secondary processor is waiting to be released from
95 * the holding pen - release it, then wait for it to flag
96 * that it has been released by resetting pen_release.
97 *
98 * Note that "pen_release" is the hardware CPU ID, whereas
99 * "cpu" is Linux's internal ID.
100 */
101 pen_release = cpu_logical_map(cpu);
102 sync_cache_w(&pen_release);
103
104 /*
105 * Send the secondary CPU a soft interrupt, thereby causing
106 * the boot monitor to read the system wide flags register,
107 * and branch to the address found there.
108 */
109 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
110
111 timeout = jiffies + (1 * HZ);
112 while (time_before(jiffies, timeout)) {
113 smp_rmb();
114 if (pen_release == -1)
115 break;
116
117 udelay(10);
118 }
119
120 /*
121 * now the secondary core is starting up let it run its
122 * calibrations, then wait for it to finish
123 */
124 spin_unlock(&boot_lock);
125
126 return pen_release != -1 ? -ENOSYS : 0;
127}
128
129/*
130 * Initialise the CPU possible map early - this describes the CPUs
131 * which may be present or become present in the system. The msm8x60
132 * does not support the ARM SCU, so just set the possible cpu mask to
133 * NR_CPUS.
134 */
135static void __init msm_smp_init_cpus(void)
136{
137 unsigned int i, ncores = get_core_count();
138
139 if (ncores > nr_cpu_ids) {
140 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
141 ncores, nr_cpu_ids);
142 ncores = nr_cpu_ids;
143 }
144
145 for (i = 0; i < ncores; i++)
146 set_cpu_possible(i, true);
147}
148
149static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
150{
151}
152
153struct smp_operations msm_smp_ops __initdata = {
154 .smp_init_cpus = msm_smp_init_cpus,
155 .smp_prepare_cpus = msm_smp_prepare_cpus,
156 .smp_secondary_init = msm_secondary_init,
157 .smp_boot_secondary = msm_boot_secondary,
158#ifdef CONFIG_HOTPLUG_CPU
159 .cpu_die = msm_cpu_die,
160#endif
161};
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 @@
1config ARCH_QCOM
2 bool "Qualcomm Support" if ARCH_MULTI_V7
3 select ARCH_REQUIRE_GPIOLIB
4 select ARM_GIC
5 select CLKSRC_OF
6 select GENERIC_CLOCKEVENTS
7 select HAVE_SMP
8 select QCOM_SCM if SMP
9 help
10 Support for Qualcomm's devicetree based systems.
11
12if ARCH_QCOM
13
14menu "Qualcomm SoC Selection"
15
16config ARCH_MSM8X60
17 bool "Enable support for MSM8X60"
18 select CLKSRC_QCOM
19
20config ARCH_MSM8960
21 bool "Enable support for MSM8960"
22 select CLKSRC_QCOM
23
24config ARCH_MSM8974
25 bool "Enable support for MSM8974"
26 select HAVE_ARM_ARCH_TIMER
27
28endmenu
29
30config QCOM_SCM
31 bool
32
33endif
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 @@
1obj-y := board.o
2obj-$(CONFIG_SMP) += platsmp.o
3obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
4
5CFLAGS_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 @@
1/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved. 1/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 4 * it under the terms of the GNU General Public License version 2 and
@@ -11,31 +11,16 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/of.h>
15#include <linux/of_platform.h>
16 14
17#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19 16
20#include "common.h" 17static const char * const qcom_dt_match[] __initconst = {
21
22static const char * const msm_dt_match[] __initconst = {
23 "qcom,msm8660-fluid",
24 "qcom,msm8660-surf", 18 "qcom,msm8660-surf",
25 "qcom,msm8960-cdp", 19 "qcom,msm8960-cdp",
26 NULL
27};
28
29static const char * const apq8074_dt_match[] __initconst = {
30 "qcom,apq8074-dragonboard", 20 "qcom,apq8074-dragonboard",
31 NULL 21 NULL
32}; 22};
33 23
34DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") 24DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
35 .smp = smp_ops(msm_smp_ops), 25 .dt_compat = qcom_dt_match,
36 .dt_compat = msm_dt_match,
37MACHINE_END
38
39DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)")
40 .dt_compat = apq8074_dt_match,
41MACHINE_END 26MACHINE_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 @@
1/*
2 * Copyright (C) 2002 ARM Ltd.
3 * All Rights Reserved
4 * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
5 * Copyright (c) 2014 The Linux Foundation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/errno.h>
14#include <linux/delay.h>
15#include <linux/device.h>
16#include <linux/of.h>
17#include <linux/of_address.h>
18#include <linux/smp.h>
19#include <linux/io.h>
20
21#include <asm/smp_plat.h>
22
23#include "scm-boot.h"
24
25#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0
26#define SCSS_CPU1CORE_RESET 0x2d80
27#define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64
28
29#define APCS_CPU_PWR_CTL 0x04
30#define PLL_CLAMP BIT(8)
31#define CORE_PWRD_UP BIT(7)
32#define COREPOR_RST BIT(5)
33#define CORE_RST BIT(4)
34#define L2DT_SLP BIT(3)
35#define CLAMP BIT(0)
36
37#define APC_PWR_GATE_CTL 0x14
38#define BHS_CNT_SHIFT 24
39#define LDO_PWR_DWN_SHIFT 16
40#define LDO_BYP_SHIFT 8
41#define BHS_SEG_SHIFT 1
42#define BHS_EN BIT(0)
43
44#define APCS_SAW2_VCTL 0x14
45#define APCS_SAW2_2_VCTL 0x1c
46
47extern void secondary_startup(void);
48
49static DEFINE_SPINLOCK(boot_lock);
50
51#ifdef CONFIG_HOTPLUG_CPU
52static void __ref qcom_cpu_die(unsigned int cpu)
53{
54 wfi();
55}
56#endif
57
58static void qcom_secondary_init(unsigned int cpu)
59{
60 /*
61 * Synchronise with the boot thread.
62 */
63 spin_lock(&boot_lock);
64 spin_unlock(&boot_lock);
65}
66
67static int scss_release_secondary(unsigned int cpu)
68{
69 struct device_node *node;
70 void __iomem *base;
71
72 node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
73 if (!node) {
74 pr_err("%s: can't find node\n", __func__);
75 return -ENXIO;
76 }
77
78 base = of_iomap(node, 0);
79 of_node_put(node);
80 if (!base)
81 return -ENOMEM;
82
83 writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
84 writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
85 writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
86 mb();
87 iounmap(base);
88
89 return 0;
90}
91
92static int kpssv1_release_secondary(unsigned int cpu)
93{
94 int ret = 0;
95 void __iomem *reg, *saw_reg;
96 struct device_node *cpu_node, *acc_node, *saw_node;
97 u32 val;
98
99 cpu_node = of_get_cpu_node(cpu, NULL);
100 if (!cpu_node)
101 return -ENODEV;
102
103 acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
104 if (!acc_node) {
105 ret = -ENODEV;
106 goto out_acc;
107 }
108
109 saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
110 if (!saw_node) {
111 ret = -ENODEV;
112 goto out_saw;
113 }
114
115 reg = of_iomap(acc_node, 0);
116 if (!reg) {
117 ret = -ENOMEM;
118 goto out_acc_map;
119 }
120
121 saw_reg = of_iomap(saw_node, 0);
122 if (!saw_reg) {
123 ret = -ENOMEM;
124 goto out_saw_map;
125 }
126
127 /* Turn on CPU rail */
128 writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
129 mb();
130 udelay(512);
131
132 /* Krait bring-up sequence */
133 val = PLL_CLAMP | L2DT_SLP | CLAMP;
134 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
135 val &= ~L2DT_SLP;
136 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
137 mb();
138 ndelay(300);
139
140 val |= COREPOR_RST;
141 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
142 mb();
143 udelay(2);
144
145 val &= ~CLAMP;
146 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
147 mb();
148 udelay(2);
149
150 val &= ~COREPOR_RST;
151 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
152 mb();
153 udelay(100);
154
155 val |= CORE_PWRD_UP;
156 writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
157 mb();
158
159 iounmap(saw_reg);
160out_saw_map:
161 iounmap(reg);
162out_acc_map:
163 of_node_put(saw_node);
164out_saw:
165 of_node_put(acc_node);
166out_acc:
167 of_node_put(cpu_node);
168 return ret;
169}
170
171static int kpssv2_release_secondary(unsigned int cpu)
172{
173 void __iomem *reg;
174 struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
175 void __iomem *l2_saw_base;
176 unsigned reg_val;
177 int ret;
178
179 cpu_node = of_get_cpu_node(cpu, NULL);
180 if (!cpu_node)
181 return -ENODEV;
182
183 acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
184 if (!acc_node) {
185 ret = -ENODEV;
186 goto out_acc;
187 }
188
189 l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
190 if (!l2_node) {
191 ret = -ENODEV;
192 goto out_l2;
193 }
194
195 saw_node = of_parse_phandle(l2_node, "qcom,saw", 0);
196 if (!saw_node) {
197 ret = -ENODEV;
198 goto out_saw;
199 }
200
201 reg = of_iomap(acc_node, 0);
202 if (!reg) {
203 ret = -ENOMEM;
204 goto out_map;
205 }
206
207 l2_saw_base = of_iomap(saw_node, 0);
208 if (!l2_saw_base) {
209 ret = -ENOMEM;
210 goto out_saw_map;
211 }
212
213 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
214 reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN;
215 writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
216 mb();
217 /* wait for the BHS to settle */
218 udelay(1);
219
220 /* Turn on BHS segments */
221 reg_val |= 0x3f << BHS_SEG_SHIFT;
222 writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
223 mb();
224 /* wait for the BHS to settle */
225 udelay(1);
226
227 /* Finally turn on the bypass so that BHS supplies power */
228 reg_val |= 0x3f << LDO_BYP_SHIFT;
229 writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
230
231 /* enable max phases */
232 writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
233 mb();
234 udelay(50);
235
236 reg_val = COREPOR_RST | CLAMP;
237 writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
238 mb();
239 udelay(2);
240
241 reg_val &= ~CLAMP;
242 writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
243 mb();
244 udelay(2);
245
246 reg_val &= ~COREPOR_RST;
247 writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
248 mb();
249
250 reg_val |= CORE_PWRD_UP;
251 writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
252 mb();
253
254 ret = 0;
255
256 iounmap(l2_saw_base);
257out_saw_map:
258 iounmap(reg);
259out_map:
260 of_node_put(saw_node);
261out_saw:
262 of_node_put(l2_node);
263out_l2:
264 of_node_put(acc_node);
265out_acc:
266 of_node_put(cpu_node);
267
268 return ret;
269}
270
271static DEFINE_PER_CPU(int, cold_boot_done);
272
273static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
274{
275 int ret = 0;
276
277 if (!per_cpu(cold_boot_done, cpu)) {
278 ret = func(cpu);
279 if (!ret)
280 per_cpu(cold_boot_done, cpu) = true;
281 }
282
283 /*
284 * set synchronisation state between this boot processor
285 * and the secondary one
286 */
287 spin_lock(&boot_lock);
288
289 /*
290 * Send the secondary CPU a soft interrupt, thereby causing
291 * the boot monitor to read the system wide flags register,
292 * and branch to the address found there.
293 */
294 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
295
296 /*
297 * now the secondary core is starting up let it run its
298 * calibrations, then wait for it to finish
299 */
300 spin_unlock(&boot_lock);
301
302 return ret;
303}
304
305static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
306{
307 return qcom_boot_secondary(cpu, scss_release_secondary);
308}
309
310static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
311{
312 return qcom_boot_secondary(cpu, kpssv1_release_secondary);
313}
314
315static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
316{
317 return qcom_boot_secondary(cpu, kpssv2_release_secondary);
318}
319
320static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
321{
322 int cpu, map;
323 unsigned int flags = 0;
324 static const int cold_boot_flags[] = {
325 0,
326 SCM_FLAG_COLDBOOT_CPU1,
327 SCM_FLAG_COLDBOOT_CPU2,
328 SCM_FLAG_COLDBOOT_CPU3,
329 };
330
331 for_each_present_cpu(cpu) {
332 map = cpu_logical_map(cpu);
333 if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) {
334 set_cpu_present(cpu, false);
335 continue;
336 }
337 flags |= cold_boot_flags[map];
338 }
339
340 if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) {
341 for_each_present_cpu(cpu) {
342 if (cpu == smp_processor_id())
343 continue;
344 set_cpu_present(cpu, false);
345 }
346 pr_warn("Failed to set CPU boot address, disabling SMP\n");
347 }
348}
349
350static struct smp_operations smp_msm8660_ops __initdata = {
351 .smp_prepare_cpus = qcom_smp_prepare_cpus,
352 .smp_secondary_init = qcom_secondary_init,
353 .smp_boot_secondary = msm8660_boot_secondary,
354#ifdef CONFIG_HOTPLUG_CPU
355 .cpu_die = qcom_cpu_die,
356#endif
357};
358CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
359
360static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
361 .smp_prepare_cpus = qcom_smp_prepare_cpus,
362 .smp_secondary_init = qcom_secondary_init,
363 .smp_boot_secondary = kpssv1_boot_secondary,
364#ifdef CONFIG_HOTPLUG_CPU
365 .cpu_die = qcom_cpu_die,
366#endif
367};
368CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
369
370static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
371 .smp_prepare_cpus = qcom_smp_prepare_cpus,
372 .smp_secondary_init = qcom_secondary_init,
373 .smp_boot_secondary = kpssv2_boot_secondary,
374#ifdef CONFIG_HOTPLUG_CPU
375 .cpu_die = qcom_cpu_die,
376#endif
377};
378CPU_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 @@
13#define __MACH_SCM_BOOT_H 13#define __MACH_SCM_BOOT_H
14 14
15#define SCM_BOOT_ADDR 0x1 15#define SCM_BOOT_ADDR 0x1
16#define SCM_FLAG_COLDBOOT_CPU1 0x1 16#define SCM_FLAG_COLDBOOT_CPU1 0x01
17#define SCM_FLAG_WARMBOOT_CPU1 0x2 17#define SCM_FLAG_COLDBOOT_CPU2 0x08
18#define SCM_FLAG_WARMBOOT_CPU0 0x4 18#define SCM_FLAG_COLDBOOT_CPU3 0x20
19#define SCM_FLAG_WARMBOOT_CPU0 0x04
20#define SCM_FLAG_WARMBOOT_CPU1 0x02
19 21
20int scm_set_boot_addr(phys_addr_t addr, int flags); 22int scm_set_boot_addr(phys_addr_t addr, int flags);
21 23
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/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cd6950fd8caf..6510ec4f45ff 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -140,3 +140,6 @@ config VF_PIT_TIMER
140 bool 140 bool
141 help 141 help
142 Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. 142 Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
143
144config CLKSRC_QCOM
145 bool
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c7ca50a9c232..2e0c0cc0a014 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
32obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o 32obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
33obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o 33obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
34obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o 34obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
35obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
35 36
36obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o 37obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
37obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o 38obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
diff --git a/arch/arm/mach-msm/timer.c b/drivers/clocksource/qcom-timer.c
index fd1644987534..e807acf4c665 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/drivers/clocksource/qcom-timer.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * 2 *
3 * Copyright (C) 2007 Google, Inc. 3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and 7 * License version 2, as published by the Free Software Foundation, and
@@ -26,10 +26,6 @@
26#include <linux/of_irq.h> 26#include <linux/of_irq.h>
27#include <linux/sched_clock.h> 27#include <linux/sched_clock.h>
28 28
29#include <asm/mach/time.h>
30
31#include "common.h"
32
33#define TIMER_MATCH_VAL 0x0000 29#define TIMER_MATCH_VAL 0x0000
34#define TIMER_COUNT_VAL 0x0004 30#define TIMER_COUNT_VAL 0x0004
35#define TIMER_ENABLE 0x0008 31#define TIMER_ENABLE 0x0008
@@ -110,15 +106,6 @@ static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
110 return readl_relaxed(source_base + TIMER_COUNT_VAL); 106 return readl_relaxed(source_base + TIMER_COUNT_VAL);
111} 107}
112 108
113static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
114{
115 /*
116 * Shift timer count down by a constant due to unreliable lower bits
117 * on some targets.
118 */
119 return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
120}
121
122static struct clocksource msm_clocksource = { 109static struct clocksource msm_clocksource = {
123 .name = "dg_timer", 110 .name = "dg_timer",
124 .rating = 300, 111 .rating = 300,
@@ -232,7 +219,7 @@ err:
232 sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); 219 sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
233} 220}
234 221
235#ifdef CONFIG_OF 222#ifdef CONFIG_ARCH_QCOM
236static void __init msm_dt_timer_init(struct device_node *np) 223static void __init msm_dt_timer_init(struct device_node *np)
237{ 224{
238 u32 freq; 225 u32 freq;
@@ -285,7 +272,7 @@ static void __init msm_dt_timer_init(struct device_node *np)
285} 272}
286CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); 273CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
287CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); 274CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
288#endif 275#else
289 276
290static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source, 277static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
291 u32 sts) 278 u32 sts)
@@ -305,6 +292,15 @@ static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
305 return 0; 292 return 0;
306} 293}
307 294
295static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
296{
297 /*
298 * Shift timer count down by a constant due to unreliable lower bits
299 * on some targets.
300 */
301 return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
302}
303
308void __init msm7x01_timer_init(void) 304void __init msm7x01_timer_init(void)
309{ 305{
310 struct clocksource *cs = &msm_clocksource; 306 struct clocksource *cs = &msm_clocksource;
@@ -331,3 +327,4 @@ void __init qsd8x50_timer_init(void)
331 return; 327 return;
332 msm_timer_init(19200000 / 4, 32, 7, false); 328 msm_timer_init(19200000 / 4, 32, 7, false);
333} 329}
330#endif
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index bc2121fa9132..bd02ca7a1d55 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -167,6 +167,15 @@
167#define CLK_OF_TABLES() 167#define CLK_OF_TABLES()
168#endif 168#endif
169 169
170#ifdef CONFIG_SMP
171#define CPU_METHOD_OF_TABLES() . = ALIGN(8); \
172 VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \
173 *(__cpu_method_of_table) \
174 VMLINUX_SYMBOL(__cpu_method_of_table_end) = .;
175#else
176#define CPU_METHOD_OF_TABLES()
177#endif
178
170#define KERNEL_DTB() \ 179#define KERNEL_DTB() \
171 STRUCT_ALIGN(); \ 180 STRUCT_ALIGN(); \
172 VMLINUX_SYMBOL(__dtb_start) = .; \ 181 VMLINUX_SYMBOL(__dtb_start) = .; \
@@ -491,6 +500,7 @@
491 MEM_DISCARD(init.rodata) \ 500 MEM_DISCARD(init.rodata) \
492 CLK_OF_TABLES() \ 501 CLK_OF_TABLES() \
493 CLKSRC_OF_TABLES() \ 502 CLKSRC_OF_TABLES() \
503 CPU_METHOD_OF_TABLES() \
494 KERNEL_DTB() \ 504 KERNEL_DTB() \
495 IRQCHIP_OF_MATCH_TABLE() 505 IRQCHIP_OF_MATCH_TABLE()
496 506