aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 17:39:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 17:39:59 -0500
commitb3c37522928b5452588fc202eaa0f11f6e339256 (patch)
tree37bfe21d9977b15271903d1a4b304289a232e364 /arch/arm
parent2ac9d7aaccbd598b5bd19ac40761b723bb675442 (diff)
parent6d0a5636fba5a3f82ec80ab124dd4748344549c3 (diff)
Merge tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
power management changes for omap and imx A significant part of the changes for these two platforms went into power management, so they are split out into a separate branch. * tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (65 commits) ARM: imx6: remove __CPUINIT annotation from v7_invalidate_l1 ARM: imx6: fix v7_invalidate_l1 by adding I-Cache invalidation ARM: imx6q: resume PL310 only when CACHE_L2X0 defined ARM: imx6q: build pm code only when CONFIG_PM selected ARM: mx5: use generic irq chip pm interface for pm functions on ARM: omap: pass minimal SoC/board data for UART from dt arm/dts: Add minimal device tree support for omap2420 and omap2430 omap-serial: Add minimal device tree support omap-serial: Use default clock speed (48Mhz) if not specified omap-serial: Get rid of all pdev->id usage ARM: OMAP2+: hwmod: Add a new flag to handle hwmods left enabled at init ARM: OMAP4: PRM: use PRCM interrupt handler ARM: OMAP3: pm: use prcm chain handler ARM: OMAP: hwmod: add support for selecting mpu_irq for each wakeup pad ARM: OMAP2+: mux: add support for PAD wakeup interrupts ARM: OMAP: PRCM: add suspend prepare / finish support ARM: OMAP: PRCM: add support for chain interrupt handler ARM: OMAP3/4: PRM: add functions to read pending IRQs, PRM barrier ARM: OMAP2+: hwmod: Add API to enable IO ring wakeup ARM: OMAP2+: mux: add wakeup-capable hwmod mux entries to dynamic list ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/boot/dts/omap2.dtsi67
-rw-r--r--arch/arm/boot/dts/omap3.dtsi31
-rw-r--r--arch/arm/boot/dts/omap4.dtsi28
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-imx/Makefile6
-rw-r--r--arch/arm/mach-imx/head-v7.S17
-rw-r--r--arch/arm/mach-imx/pm-imx6q.c2
-rw-r--r--arch/arm/mach-mx5/mm.c19
-rw-r--r--arch/arm/mach-mx5/system.c3
-rw-r--r--arch/arm/mach-omap2/Kconfig21
-rw-r--r--arch/arm/mach-omap2/Makefile19
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c100
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c68
-rw-r--r--arch/arm/mach-omap2/board-generic.c1
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c6
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c68
-rw-r--r--arch/arm/mach-omap2/common.h64
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c21
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c245
-rw-r--r--arch/arm/mach-omap2/include/mach/barriers.h31
-rw-r--r--arch/arm/mach-omap2/include/mach/omap-secure.h57
-rw-r--r--arch/arm/mach-omap2/include/mach/omap-wakeupgen.h39
-rw-r--r--arch/arm/mach-omap2/io.c9
-rw-r--r--arch/arm/mach-omap2/mux.c89
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S5
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c14
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c398
-rw-r--r--arch/arm/mach-omap2/omap-secure.c81
-rw-r--r--arch/arm/mach-omap2/omap-smc.S (renamed from arch/arm/mach-omap2/omap44xx-smc.S)23
-rw-r--r--arch/arm/mach-omap2/omap-smp.c45
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.c389
-rw-r--r--arch/arm/mach-omap2/omap4-common.c94
-rw-r--r--arch/arm/mach-omap2/omap4-sar-layout.h50
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c125
-rw-r--r--arch/arm/mach-omap2/pm.h1
-rw-r--r--arch/arm/mach-omap2/pm24xx.c20
-rw-r--r--arch/arm/mach-omap2/pm34xx.c158
-rw-r--r--arch/arm/mach-omap2/pm44xx.c153
-rw-r--r--arch/arm/mach-omap2/prcm-common.h75
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c97
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h9
-rw-r--r--arch/arm/mach-omap2/prm44xx.c116
-rw-r--r--arch/arm/mach-omap2/prm44xx.h8
-rw-r--r--arch/arm/mach-omap2/prm_common.c320
-rw-r--r--arch/arm/mach-omap2/serial.c907
-rw-r--r--arch/arm/mach-omap2/sleep44xx.S379
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h2
-rw-r--r--arch/arm/plat-mxc/tzic.c40
-rw-r--r--arch/arm/plat-omap/common.c3
-rw-r--r--arch/arm/plat-omap/include/plat/omap-secure.h13
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h37
-rw-r--r--arch/arm/plat-omap/include/plat/omap44xx.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h6
-rw-r--r--arch/arm/plat-omap/include/plat/serial.h10
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h6
-rw-r--r--arch/arm/plat-omap/sram.c8
57 files changed, 3494 insertions, 1119 deletions
diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi
new file mode 100644
index 000000000000..f2ab4ea7cc0e
--- /dev/null
+++ b/arch/arm/boot/dts/omap2.dtsi
@@ -0,0 +1,67 @@
1/*
2 * Device Tree Source for OMAP2 SoC
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11/include/ "skeleton.dtsi"
12
13/ {
14 compatible = "ti,omap2430", "ti,omap2420", "ti,omap2";
15
16 aliases {
17 serial0 = &uart1;
18 serial1 = &uart2;
19 serial2 = &uart3;
20 };
21
22 cpus {
23 cpu@0 {
24 compatible = "arm,arm1136jf-s";
25 };
26 };
27
28 soc {
29 compatible = "ti,omap-infra";
30 mpu {
31 compatible = "ti,omap2-mpu";
32 ti,hwmods = "mpu";
33 };
34 };
35
36 ocp {
37 compatible = "simple-bus";
38 #address-cells = <1>;
39 #size-cells = <1>;
40 ranges;
41 ti,hwmods = "l3_main";
42
43 intc: interrupt-controller@1 {
44 compatible = "ti,omap2-intc";
45 interrupt-controller;
46 #interrupt-cells = <1>;
47 };
48
49 uart1: serial@4806a000 {
50 compatible = "ti,omap2-uart";
51 ti,hwmods = "uart1";
52 clock-frequency = <48000000>;
53 };
54
55 uart2: serial@4806c000 {
56 compatible = "ti,omap2-uart";
57 ti,hwmods = "uart2";
58 clock-frequency = <48000000>;
59 };
60
61 uart3: serial@4806e000 {
62 compatible = "ti,omap2-uart";
63 ti,hwmods = "uart3";
64 clock-frequency = <48000000>;
65 };
66 };
67};
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index d202bb5ec7ef..216c3317461d 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -13,6 +13,13 @@
13/ { 13/ {
14 compatible = "ti,omap3430", "ti,omap3"; 14 compatible = "ti,omap3430", "ti,omap3";
15 15
16 aliases {
17 serial0 = &uart1;
18 serial1 = &uart2;
19 serial2 = &uart3;
20 serial3 = &uart4;
21 };
22
16 cpus { 23 cpus {
17 cpu@0 { 24 cpu@0 {
18 compatible = "arm,cortex-a8"; 25 compatible = "arm,cortex-a8";
@@ -59,5 +66,29 @@
59 interrupt-controller; 66 interrupt-controller;
60 #interrupt-cells = <1>; 67 #interrupt-cells = <1>;
61 }; 68 };
69
70 uart1: serial@0x4806a000 {
71 compatible = "ti,omap3-uart";
72 ti,hwmods = "uart1";
73 clock-frequency = <48000000>;
74 };
75
76 uart2: serial@0x4806c000 {
77 compatible = "ti,omap3-uart";
78 ti,hwmods = "uart2";
79 clock-frequency = <48000000>;
80 };
81
82 uart3: serial@0x49020000 {
83 compatible = "ti,omap3-uart";
84 ti,hwmods = "uart3";
85 clock-frequency = <48000000>;
86 };
87
88 uart4: serial@0x49042000 {
89 compatible = "ti,omap3-uart";
90 ti,hwmods = "uart4";
91 clock-frequency = <48000000>;
92 };
62 }; 93 };
63}; 94};
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 4c61c829043a..e8fe75fac7c5 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -21,6 +21,10 @@
21 interrupt-parent = <&gic>; 21 interrupt-parent = <&gic>;
22 22
23 aliases { 23 aliases {
24 serial0 = &uart1;
25 serial1 = &uart2;
26 serial2 = &uart3;
27 serial3 = &uart4;
24 }; 28 };
25 29
26 cpus { 30 cpus {
@@ -99,5 +103,29 @@
99 reg = <0x48241000 0x1000>, 103 reg = <0x48241000 0x1000>,
100 <0x48240100 0x0100>; 104 <0x48240100 0x0100>;
101 }; 105 };
106
107 uart1: serial@0x4806a000 {
108 compatible = "ti,omap4-uart";
109 ti,hwmods = "uart1";
110 clock-frequency = <48000000>;
111 };
112
113 uart2: serial@0x4806c000 {
114 compatible = "ti,omap4-uart";
115 ti,hwmods = "uart2";
116 clock-frequency = <48000000>;
117 };
118
119 uart3: serial@0x48020000 {
120 compatible = "ti,omap4-uart";
121 ti,hwmods = "uart3";
122 clock-frequency = <48000000>;
123 };
124
125 uart4: serial@0x4806e000 {
126 compatible = "ti,omap4-uart";
127 ti,hwmods = "uart4";
128 clock-frequency = <48000000>;
129 };
102 }; 130 };
103}; 131};
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 9d8598f29fda..0e6de366c648 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -596,6 +596,7 @@ comment "i.MX6 family:"
596 596
597config SOC_IMX6Q 597config SOC_IMX6Q
598 bool "i.MX6 Quad support" 598 bool "i.MX6 Quad support"
599 select ARM_CPU_SUSPEND if PM
599 select ARM_GIC 600 select ARM_GIC
600 select CPU_V7 601 select CPU_V7
601 select HAVE_ARM_SCU 602 select HAVE_ARM_SCU
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d97f409ce98b..f5920c24f7d7 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -70,4 +70,8 @@ AFLAGS_head-v7.o :=-Wa,-march=armv7-a
70obj-$(CONFIG_SMP) += platsmp.o 70obj-$(CONFIG_SMP) += platsmp.o
71obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 71obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
72obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 72obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
73obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o pm-imx6q.o 73obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
74
75ifeq ($(CONFIG_PM),y)
76obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o
77endif
diff --git a/arch/arm/mach-imx/head-v7.S b/arch/arm/mach-imx/head-v7.S
index 6229efbc70cb..7e49deb128a4 100644
--- a/arch/arm/mach-imx/head-v7.S
+++ b/arch/arm/mach-imx/head-v7.S
@@ -16,7 +16,6 @@
16#include <asm/hardware/cache-l2x0.h> 16#include <asm/hardware/cache-l2x0.h>
17 17
18 .section ".text.head", "ax" 18 .section ".text.head", "ax"
19 __CPUINIT
20 19
21/* 20/*
22 * The secondary kernel init calls v7_flush_dcache_all before it enables 21 * The secondary kernel init calls v7_flush_dcache_all before it enables
@@ -33,6 +32,7 @@
33 */ 32 */
34ENTRY(v7_invalidate_l1) 33ENTRY(v7_invalidate_l1)
35 mov r0, #0 34 mov r0, #0
35 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
36 mcr p15, 2, r0, c0, c0, 0 36 mcr p15, 2, r0, c0, c0, 0
37 mrc p15, 1, r0, c0, c0, 0 37 mrc p15, 1, r0, c0, c0, 0
38 38
@@ -71,6 +71,7 @@ ENTRY(v7_secondary_startup)
71ENDPROC(v7_secondary_startup) 71ENDPROC(v7_secondary_startup)
72#endif 72#endif
73 73
74#ifdef CONFIG_PM
74/* 75/*
75 * The following code is located into the .data section. This is to 76 * The following code is located into the .data section. This is to
76 * allow phys_l2x0_saved_regs to be accessed with a relative load 77 * allow phys_l2x0_saved_regs to be accessed with a relative load
@@ -79,6 +80,7 @@ ENDPROC(v7_secondary_startup)
79 .data 80 .data
80 .align 81 .align
81 82
83#ifdef CONFIG_CACHE_L2X0
82 .macro pl310_resume 84 .macro pl310_resume
83 ldr r2, phys_l2x0_saved_regs 85 ldr r2, phys_l2x0_saved_regs
84 ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0 86 ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
@@ -88,12 +90,17 @@ ENDPROC(v7_secondary_startup)
88 str r1, [r0, #L2X0_CTRL] @ re-enable L2 90 str r1, [r0, #L2X0_CTRL] @ re-enable L2
89 .endm 91 .endm
90 92
93 .globl phys_l2x0_saved_regs
94phys_l2x0_saved_regs:
95 .long 0
96#else
97 .macro pl310_resume
98 .endm
99#endif
100
91ENTRY(v7_cpu_resume) 101ENTRY(v7_cpu_resume)
92 bl v7_invalidate_l1 102 bl v7_invalidate_l1
93 pl310_resume 103 pl310_resume
94 b cpu_resume 104 b cpu_resume
95ENDPROC(v7_cpu_resume) 105ENDPROC(v7_cpu_resume)
96 106#endif
97 .globl phys_l2x0_saved_regs
98phys_l2x0_saved_regs:
99 .long 0
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
index f20f191d7cca..f7b0c2b1b905 100644
--- a/arch/arm/mach-imx/pm-imx6q.c
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -64,7 +64,9 @@ void __init imx6q_pm_init(void)
64 * address of the data structure used by l2x0 core to save registers, 64 * address of the data structure used by l2x0 core to save registers,
65 * and later restore the necessary ones in imx6q resume entry. 65 * and later restore the necessary ones in imx6q resume entry.
66 */ 66 */
67#ifdef CONFIG_CACHE_L2X0
67 phys_l2x0_saved_regs = __pa(&l2x0_saved_regs); 68 phys_l2x0_saved_regs = __pa(&l2x0_saved_regs);
69#endif
68 70
69 suspend_set_ops(&imx6q_pm_ops); 71 suspend_set_ops(&imx6q_pm_ops);
70} 72}
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index df4a508f240a..bc17dfea3817 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/clk.h>
16 17
17#include <asm/mach/map.h> 18#include <asm/mach/map.h>
18 19
@@ -21,10 +22,26 @@
21#include <mach/devices-common.h> 22#include <mach/devices-common.h>
22#include <mach/iomux-v3.h> 23#include <mach/iomux-v3.h>
23 24
25static struct clk *gpc_dvfs_clk;
26
24static void imx5_idle(void) 27static void imx5_idle(void)
25{ 28{
26 if (!need_resched()) 29 if (!need_resched()) {
30 /* gpc clock is needed for SRPG */
31 if (gpc_dvfs_clk == NULL) {
32 gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
33 if (IS_ERR(gpc_dvfs_clk))
34 goto err0;
35 }
36 clk_enable(gpc_dvfs_clk);
27 mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); 37 mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
38 if (tzic_enable_wake())
39 goto err1;
40 cpu_do_idle();
41err1:
42 clk_disable(gpc_dvfs_clk);
43 }
44err0:
28 local_irq_enable(); 45 local_irq_enable();
29} 46}
30 47
diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c
index 144ebebc4a61..5eebfaad1226 100644
--- a/arch/arm/mach-mx5/system.c
+++ b/arch/arm/mach-mx5/system.c
@@ -55,9 +55,6 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
55 stop_mode = 1; 55 stop_mode = 1;
56 } 56 }
57 arm_srpgcr |= MXC_SRPGCR_PCR; 57 arm_srpgcr |= MXC_SRPGCR_PCR;
58
59 if (tzic_enable_wake(1) != 0)
60 return;
61 break; 58 break;
62 case STOP_POWER_ON: 59 case STOP_POWER_ON:
63 ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET; 60 ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b7407154c881..904bd1dfcd2e 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -365,6 +365,27 @@ config OMAP3_SDRC_AC_TIMING
365 wish to say no. Selecting yes without understanding what is 365 wish to say no. Selecting yes without understanding what is
366 going on could result in system crashes; 366 going on could result in system crashes;
367 367
368config OMAP4_ERRATA_I688
369 bool "OMAP4 errata: Async Bridge Corruption"
370 depends on ARCH_OMAP4
371 select ARCH_HAS_BARRIERS
372 help
373 If a data is stalled inside asynchronous bridge because of back
374 pressure, it may be accepted multiple times, creating pointer
375 misalignment that will corrupt next transfers on that data path
376 until next reset of the system (No recovery procedure once the
377 issue is hit, the path remains consistently broken). Async bridge
378 can be found on path between MPU to EMIF and MPU to L3 interconnect.
379 This situation can happen only when the idle is initiated by a
380 Master Request Disconnection (which is trigged by software when
381 executing WFI on CPU).
382 The work-around for this errata needs all the initiators connected
383 through async bridge must ensure that data path is properly drained
384 before issuing WFI. This condition will be met if one Strongly ordered
385 access is performed to the target right before executing the WFI.
386 In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained.
387 IO barrier ensure that there is no synchronisation loss on initiators
388 operating on both interconnect port simultaneously.
368endmenu 389endmenu
369 390
370endif 391endif
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 6d226a76d057..fc9b238cbc19 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -11,10 +11,11 @@ hwmod-common = omap_hwmod.o \
11 omap_hwmod_common_data.o 11 omap_hwmod_common_data.o
12clock-common = clock.o clock_common_data.o \ 12clock-common = clock.o clock_common_data.o \
13 clkt_dpll.o clkt_clksel.o 13 clkt_dpll.o clkt_clksel.o
14secure-common = omap-smc.o omap-secure.o
14 15
15obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) 16obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
16obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) 17obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
17obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) 18obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
18 19
19obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
20 21
@@ -24,11 +25,13 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
24obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o 25obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
25obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o 26obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
26obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o 27obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
27obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o 28obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \
29 sleep44xx.o
28 30
29plus_sec := $(call as-instr,.arch_extension sec,+sec) 31plus_sec := $(call as-instr,.arch_extension sec,+sec)
30AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) 32AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
31AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a$(plus_sec) 33AFLAGS_omap-smc.o :=-Wa,-march=armv7-a$(plus_sec)
34AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a$(plus_sec)
32 35
33# Functions loaded to SRAM 36# Functions loaded to SRAM
34obj-$(CONFIG_SOC_OMAP2420) += sram242x.o 37obj-$(CONFIG_SOC_OMAP2420) += sram242x.o
@@ -62,7 +65,8 @@ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
62obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o 65obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
63obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ 66obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \
64 cpuidle34xx.o 67 cpuidle34xx.o
65obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o 68obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \
69 cpuidle44xx.o
66obj-$(CONFIG_PM_DEBUG) += pm-debug.o 70obj-$(CONFIG_PM_DEBUG) += pm-debug.o
67obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o 71obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
68obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o 72obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
@@ -77,6 +81,7 @@ endif
77endif 81endif
78 82
79# PRCM 83# PRCM
84obj-y += prm_common.o
80obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o 85obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
81obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \ 86obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
82 vc3xxx_data.o vp3xxx_data.o 87 vc3xxx_data.o vp3xxx_data.o
@@ -86,7 +91,7 @@ obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
86obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \ 91obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
87 cm44xx.o prcm_mpu44xx.o \ 92 cm44xx.o prcm_mpu44xx.o \
88 prminst44xx.o vc44xx_data.o \ 93 prminst44xx.o vc44xx_data.o \
89 vp44xx_data.o 94 vp44xx_data.o prm44xx.o
90 95
91# OMAP voltage domains 96# OMAP voltage domains
92voltagedomain-common := voltage.o vc.o vp.o 97voltagedomain-common := voltage.o vc.o vp.o
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 9996334cb687..383717ba63b9 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -475,106 +475,8 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
475static struct omap_board_mux board_mux[] __initdata = { 475static struct omap_board_mux board_mux[] __initdata = {
476 { .reg_offset = OMAP_MUX_TERMINATOR }, 476 { .reg_offset = OMAP_MUX_TERMINATOR },
477}; 477};
478
479static struct omap_device_pad serial1_pads[] __initdata = {
480 /*
481 * Note that off output enable is an active low
482 * signal. So setting this means pin is a
483 * input enabled in off mode
484 */
485 OMAP_MUX_STATIC("uart1_cts.uart1_cts",
486 OMAP_PIN_INPUT |
487 OMAP_PIN_OFF_INPUT_PULLDOWN |
488 OMAP_OFFOUT_EN |
489 OMAP_MUX_MODE0),
490 OMAP_MUX_STATIC("uart1_rts.uart1_rts",
491 OMAP_PIN_OUTPUT |
492 OMAP_OFF_EN |
493 OMAP_MUX_MODE0),
494 OMAP_MUX_STATIC("uart1_rx.uart1_rx",
495 OMAP_PIN_INPUT |
496 OMAP_PIN_OFF_INPUT_PULLDOWN |
497 OMAP_OFFOUT_EN |
498 OMAP_MUX_MODE0),
499 OMAP_MUX_STATIC("uart1_tx.uart1_tx",
500 OMAP_PIN_OUTPUT |
501 OMAP_OFF_EN |
502 OMAP_MUX_MODE0),
503};
504
505static struct omap_device_pad serial2_pads[] __initdata = {
506 OMAP_MUX_STATIC("uart2_cts.uart2_cts",
507 OMAP_PIN_INPUT_PULLUP |
508 OMAP_PIN_OFF_INPUT_PULLDOWN |
509 OMAP_OFFOUT_EN |
510 OMAP_MUX_MODE0),
511 OMAP_MUX_STATIC("uart2_rts.uart2_rts",
512 OMAP_PIN_OUTPUT |
513 OMAP_OFF_EN |
514 OMAP_MUX_MODE0),
515 OMAP_MUX_STATIC("uart2_rx.uart2_rx",
516 OMAP_PIN_INPUT |
517 OMAP_PIN_OFF_INPUT_PULLDOWN |
518 OMAP_OFFOUT_EN |
519 OMAP_MUX_MODE0),
520 OMAP_MUX_STATIC("uart2_tx.uart2_tx",
521 OMAP_PIN_OUTPUT |
522 OMAP_OFF_EN |
523 OMAP_MUX_MODE0),
524};
525
526static struct omap_device_pad serial3_pads[] __initdata = {
527 OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
528 OMAP_PIN_INPUT_PULLDOWN |
529 OMAP_PIN_OFF_INPUT_PULLDOWN |
530 OMAP_OFFOUT_EN |
531 OMAP_MUX_MODE0),
532 OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
533 OMAP_PIN_OUTPUT |
534 OMAP_OFF_EN |
535 OMAP_MUX_MODE0),
536 OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
537 OMAP_PIN_INPUT |
538 OMAP_PIN_OFF_INPUT_PULLDOWN |
539 OMAP_OFFOUT_EN |
540 OMAP_MUX_MODE0),
541 OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
542 OMAP_PIN_OUTPUT |
543 OMAP_OFF_EN |
544 OMAP_MUX_MODE0),
545};
546
547static struct omap_board_data serial1_data __initdata = {
548 .id = 0,
549 .pads = serial1_pads,
550 .pads_cnt = ARRAY_SIZE(serial1_pads),
551};
552
553static struct omap_board_data serial2_data __initdata = {
554 .id = 1,
555 .pads = serial2_pads,
556 .pads_cnt = ARRAY_SIZE(serial2_pads),
557};
558
559static struct omap_board_data serial3_data __initdata = {
560 .id = 2,
561 .pads = serial3_pads,
562 .pads_cnt = ARRAY_SIZE(serial3_pads),
563};
564
565static inline void board_serial_init(void)
566{
567 omap_serial_init_port(&serial1_data);
568 omap_serial_init_port(&serial2_data);
569 omap_serial_init_port(&serial3_data);
570}
571#else 478#else
572#define board_mux NULL 479#define board_mux NULL
573
574static inline void board_serial_init(void)
575{
576 omap_serial_init();
577}
578#endif 480#endif
579 481
580/* 482/*
@@ -711,7 +613,7 @@ static void __init omap_3430sdp_init(void)
711 else 613 else
712 gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1; 614 gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
713 omap_ads7846_init(1, gpio_pendown, 310, NULL); 615 omap_ads7846_init(1, gpio_pendown, 310, NULL);
714 board_serial_init(); 616 omap_serial_init();
715 omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL); 617 omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
716 usb_musb_init(NULL); 618 usb_musb_init(NULL);
717 board_smc91x_init(); 619 board_smc91x_init();
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 4b4c9e25a83e..2ceb75d21eb2 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -844,74 +844,8 @@ static struct omap_board_mux board_mux[] __initdata = {
844 { .reg_offset = OMAP_MUX_TERMINATOR }, 844 { .reg_offset = OMAP_MUX_TERMINATOR },
845}; 845};
846 846
847static struct omap_device_pad serial2_pads[] __initdata = {
848 OMAP_MUX_STATIC("uart2_cts.uart2_cts",
849 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
850 OMAP_MUX_STATIC("uart2_rts.uart2_rts",
851 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
852 OMAP_MUX_STATIC("uart2_rx.uart2_rx",
853 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
854 OMAP_MUX_STATIC("uart2_tx.uart2_tx",
855 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
856};
857
858static struct omap_device_pad serial3_pads[] __initdata = {
859 OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
860 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
861 OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
862 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
863 OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
864 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
865 OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
866 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
867};
868
869static struct omap_device_pad serial4_pads[] __initdata = {
870 OMAP_MUX_STATIC("uart4_rx.uart4_rx",
871 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
872 OMAP_MUX_STATIC("uart4_tx.uart4_tx",
873 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
874};
875
876static struct omap_board_data serial2_data __initdata = {
877 .id = 1,
878 .pads = serial2_pads,
879 .pads_cnt = ARRAY_SIZE(serial2_pads),
880};
881
882static struct omap_board_data serial3_data __initdata = {
883 .id = 2,
884 .pads = serial3_pads,
885 .pads_cnt = ARRAY_SIZE(serial3_pads),
886};
887
888static struct omap_board_data serial4_data __initdata = {
889 .id = 3,
890 .pads = serial4_pads,
891 .pads_cnt = ARRAY_SIZE(serial4_pads),
892};
893
894static inline void board_serial_init(void)
895{
896 struct omap_board_data bdata;
897 bdata.flags = 0;
898 bdata.pads = NULL;
899 bdata.pads_cnt = 0;
900 bdata.id = 0;
901 /* pass dummy data for UART1 */
902 omap_serial_init_port(&bdata);
903
904 omap_serial_init_port(&serial2_data);
905 omap_serial_init_port(&serial3_data);
906 omap_serial_init_port(&serial4_data);
907}
908#else 847#else
909#define board_mux NULL 848#define board_mux NULL
910
911static inline void board_serial_init(void)
912{
913 omap_serial_init();
914}
915 #endif 849 #endif
916 850
917static void omap4_sdp4430_wifi_mux_init(void) 851static void omap4_sdp4430_wifi_mux_init(void)
@@ -961,7 +895,7 @@ static void __init omap_4430sdp_init(void)
961 omap4_i2c_init(); 895 omap4_i2c_init();
962 omap_sfh7741prox_init(); 896 omap_sfh7741prox_init();
963 platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); 897 platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
964 board_serial_init(); 898 omap_serial_init();
965 omap_sdrc_init(NULL, NULL); 899 omap_sdrc_init(NULL, NULL);
966 omap4_sdp4430_wifi_init(); 900 omap4_sdp4430_wifi_init();
967 omap4_twl6030_hsmmc_init(mmc); 901 omap4_twl6030_hsmmc_init(mmc);
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index f8c5b2cc7c9c..d58756060483 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -69,7 +69,6 @@ static void __init omap_generic_init(void)
69 if (node) 69 if (node)
70 irq_domain_add_simple(node, 0); 70 irq_domain_add_simple(node, 0);
71 71
72 omap_serial_init();
73 omap_sdrc_init(NULL, NULL); 72 omap_sdrc_init(NULL, NULL);
74 73
75 of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); 74 of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 72d76ed94a65..42a4d11fad23 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -644,15 +644,15 @@ static inline void board_serial_init(void)
644 bdata.pads_cnt = 0; 644 bdata.pads_cnt = 0;
645 645
646 bdata.id = 0; 646 bdata.id = 0;
647 omap_serial_init_port(&bdata); 647 omap_serial_init_port(&bdata, NULL);
648 648
649 bdata.id = 1; 649 bdata.id = 1;
650 omap_serial_init_port(&bdata); 650 omap_serial_init_port(&bdata, NULL);
651 651
652 bdata.id = 2; 652 bdata.id = 2;
653 bdata.pads = serial2_pads; 653 bdata.pads = serial2_pads;
654 bdata.pads_cnt = ARRAY_SIZE(serial2_pads); 654 bdata.pads_cnt = ARRAY_SIZE(serial2_pads);
655 omap_serial_init_port(&bdata); 655 omap_serial_init_port(&bdata, NULL);
656} 656}
657 657
658#else 658#else
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 8b06c6a60d02..e96a2e7ad36f 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -364,74 +364,8 @@ static struct omap_board_mux board_mux[] __initdata = {
364 { .reg_offset = OMAP_MUX_TERMINATOR }, 364 { .reg_offset = OMAP_MUX_TERMINATOR },
365}; 365};
366 366
367static struct omap_device_pad serial2_pads[] __initdata = {
368 OMAP_MUX_STATIC("uart2_cts.uart2_cts",
369 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
370 OMAP_MUX_STATIC("uart2_rts.uart2_rts",
371 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
372 OMAP_MUX_STATIC("uart2_rx.uart2_rx",
373 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
374 OMAP_MUX_STATIC("uart2_tx.uart2_tx",
375 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
376};
377
378static struct omap_device_pad serial3_pads[] __initdata = {
379 OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
380 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
381 OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
382 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
383 OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
384 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
385 OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
386 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
387};
388
389static struct omap_device_pad serial4_pads[] __initdata = {
390 OMAP_MUX_STATIC("uart4_rx.uart4_rx",
391 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
392 OMAP_MUX_STATIC("uart4_tx.uart4_tx",
393 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
394};
395
396static struct omap_board_data serial2_data __initdata = {
397 .id = 1,
398 .pads = serial2_pads,
399 .pads_cnt = ARRAY_SIZE(serial2_pads),
400};
401
402static struct omap_board_data serial3_data __initdata = {
403 .id = 2,
404 .pads = serial3_pads,
405 .pads_cnt = ARRAY_SIZE(serial3_pads),
406};
407
408static struct omap_board_data serial4_data __initdata = {
409 .id = 3,
410 .pads = serial4_pads,
411 .pads_cnt = ARRAY_SIZE(serial4_pads),
412};
413
414static inline void board_serial_init(void)
415{
416 struct omap_board_data bdata;
417 bdata.flags = 0;
418 bdata.pads = NULL;
419 bdata.pads_cnt = 0;
420 bdata.id = 0;
421 /* pass dummy data for UART1 */
422 omap_serial_init_port(&bdata);
423
424 omap_serial_init_port(&serial2_data);
425 omap_serial_init_port(&serial3_data);
426 omap_serial_init_port(&serial4_data);
427}
428#else 367#else
429#define board_mux NULL 368#define board_mux NULL
430
431static inline void board_serial_init(void)
432{
433 omap_serial_init();
434}
435#endif 369#endif
436 370
437/* Display DVI */ 371/* Display DVI */
@@ -562,7 +496,7 @@ static void __init omap4_panda_init(void)
562 omap4_panda_i2c_init(); 496 omap4_panda_i2c_init();
563 platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); 497 platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
564 platform_device_register(&omap_vwlan_device); 498 platform_device_register(&omap_vwlan_device);
565 board_serial_init(); 499 omap_serial_init();
566 omap_sdrc_init(NULL, NULL); 500 omap_sdrc_init(NULL, NULL);
567 omap4_twl6030_hsmmc_init(mmc); 501 omap4_twl6030_hsmmc_init(mmc);
568 omap4_ehci_init(); 502 omap4_ehci_init();
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 9403b2ce6c85..febffde2ff10 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -24,9 +24,11 @@
24 24
25#ifndef __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H 25#ifndef __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H
26#define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H 26#define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H
27#ifndef __ASSEMBLER__
27 28
28#include <linux/delay.h> 29#include <linux/delay.h>
29#include <plat/common.h> 30#include <plat/common.h>
31#include <asm/proc-fns.h>
30 32
31#ifdef CONFIG_SOC_OMAP2420 33#ifdef CONFIG_SOC_OMAP2420
32extern void omap242x_map_common_io(void); 34extern void omap242x_map_common_io(void);
@@ -168,23 +170,23 @@ void omap3_intc_resume_idle(void);
168void omap2_intc_handle_irq(struct pt_regs *regs); 170void omap2_intc_handle_irq(struct pt_regs *regs);
169void omap3_intc_handle_irq(struct pt_regs *regs); 171void omap3_intc_handle_irq(struct pt_regs *regs);
170 172
171/* 173#ifdef CONFIG_CACHE_L2X0
172 * wfi used in low power code. Directly opcode is used instead 174extern void __iomem *omap4_get_l2cache_base(void);
173 * of instruction to avoid mulit-omap build break
174 */
175#ifdef CONFIG_THUMB2_KERNEL
176#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory")
177#else
178#define do_wfi() \
179 __asm__ __volatile__ (".word 0xe320f003" : : : "memory")
180#endif 175#endif
181 176
182#ifdef CONFIG_CACHE_L2X0 177#ifdef CONFIG_SMP
183extern void __iomem *l2cache_base; 178extern void __iomem *omap4_get_scu_base(void);
179#else
180static inline void __iomem *omap4_get_scu_base(void)
181{
182 return NULL;
183}
184#endif 184#endif
185 185
186extern void __init gic_init_irq(void); 186extern void __init gic_init_irq(void);
187extern void omap_smc1(u32 fn, u32 arg); 187extern void omap_smc1(u32 fn, u32 arg);
188extern void __iomem *omap4_get_sar_ram_base(void);
189extern void omap_do_wfi(void);
188 190
189#ifdef CONFIG_SMP 191#ifdef CONFIG_SMP
190/* Needed for secondary core boot */ 192/* Needed for secondary core boot */
@@ -194,4 +196,44 @@ extern void omap_auxcoreboot_addr(u32 cpu_addr);
194extern u32 omap_read_auxcoreboot0(void); 196extern u32 omap_read_auxcoreboot0(void);
195#endif 197#endif
196 198
199#if defined(CONFIG_SMP) && defined(CONFIG_PM)
200extern int omap4_mpuss_init(void);
201extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
202extern int omap4_finish_suspend(unsigned long cpu_state);
203extern void omap4_cpu_resume(void);
204extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
205extern u32 omap4_mpuss_read_prev_context_state(void);
206#else
207static inline int omap4_enter_lowpower(unsigned int cpu,
208 unsigned int power_state)
209{
210 cpu_do_idle();
211 return 0;
212}
213
214static inline int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
215{
216 cpu_do_idle();
217 return 0;
218}
219
220static inline int omap4_mpuss_init(void)
221{
222 return 0;
223}
224
225static inline int omap4_finish_suspend(unsigned long cpu_state)
226{
227 return 0;
228}
229
230static inline void omap4_cpu_resume(void)
231{}
232
233static inline u32 omap4_mpuss_read_prev_context_state(void)
234{
235 return 0;
236}
237#endif
238#endif /* __ASSEMBLER__ */
197#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ 239#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index e20332f4abdc..464cffde58fe 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -25,12 +25,12 @@
25#include <linux/sched.h> 25#include <linux/sched.h>
26#include <linux/cpuidle.h> 26#include <linux/cpuidle.h>
27#include <linux/export.h> 27#include <linux/export.h>
28#include <linux/cpu_pm.h>
28 29
29#include <plat/prcm.h> 30#include <plat/prcm.h>
30#include <plat/irqs.h> 31#include <plat/irqs.h>
31#include "powerdomain.h" 32#include "powerdomain.h"
32#include "clockdomain.h" 33#include "clockdomain.h"
33#include <plat/serial.h>
34 34
35#include "pm.h" 35#include "pm.h"
36#include "control.h" 36#include "control.h"
@@ -124,9 +124,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
124 pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); 124 pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
125 } 125 }
126 126
127 /*
128 * Call idle CPU PM enter notifier chain so that
129 * VFP context is saved.
130 */
131 if (mpu_state == PWRDM_POWER_OFF)
132 cpu_pm_enter();
133
127 /* Execute ARM wfi */ 134 /* Execute ARM wfi */
128 omap_sram_idle(); 135 omap_sram_idle();
129 136
137 /*
138 * Call idle CPU PM enter notifier chain to restore
139 * VFP context.
140 */
141 if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
142 cpu_pm_exit();
143
130 /* Re-allow idle for C1 */ 144 /* Re-allow idle for C1 */
131 if (index == 0) { 145 if (index == 0) {
132 pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); 146 pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
@@ -245,11 +259,6 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
245 struct omap3_idle_statedata *cx; 259 struct omap3_idle_statedata *cx;
246 int ret; 260 int ret;
247 261
248 if (!omap3_can_sleep()) {
249 new_state_idx = drv->safe_state_index;
250 goto select_state;
251 }
252
253 /* 262 /*
254 * Prevent idle completely if CAM is active. 263 * Prevent idle completely if CAM is active.
255 * CAM does not have wakeup capability in OMAP3. 264 * CAM does not have wakeup capability in OMAP3.
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
new file mode 100644
index 000000000000..cfdbb86bc84e
--- /dev/null
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -0,0 +1,245 @@
1/*
2 * OMAP4 CPU idle Routines
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 * Rajendra Nayak <rnayak@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/sched.h>
14#include <linux/cpuidle.h>
15#include <linux/cpu_pm.h>
16#include <linux/export.h>
17#include <linux/clockchips.h>
18
19#include <asm/proc-fns.h>
20
21#include "common.h"
22#include "pm.h"
23#include "prm.h"
24
25#ifdef CONFIG_CPU_IDLE
26
27/* Machine specific information to be recorded in the C-state driver_data */
28struct omap4_idle_statedata {
29 u32 cpu_state;
30 u32 mpu_logic_state;
31 u32 mpu_state;
32 u8 valid;
33};
34
35static struct cpuidle_params cpuidle_params_table[] = {
36 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
37 {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1},
38 /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */
39 {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1},
40 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
41 {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1},
42};
43
44#define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
45
46struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES];
47static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd;
48
49/**
50 * omap4_enter_idle - Programs OMAP4 to enter the specified state
51 * @dev: cpuidle device
52 * @drv: cpuidle driver
53 * @index: the index of state to be entered
54 *
55 * Called from the CPUidle framework to program the device to the
56 * specified low power state selected by the governor.
57 * Returns the amount of time spent in the low power state.
58 */
59static int omap4_enter_idle(struct cpuidle_device *dev,
60 struct cpuidle_driver *drv,
61 int index)
62{
63 struct omap4_idle_statedata *cx =
64 cpuidle_get_statedata(&dev->states_usage[index]);
65 struct timespec ts_preidle, ts_postidle, ts_idle;
66 u32 cpu1_state;
67 int idle_time;
68 int new_state_idx;
69 int cpu_id = smp_processor_id();
70
71 /* Used to keep track of the total time in idle */
72 getnstimeofday(&ts_preidle);
73
74 local_irq_disable();
75 local_fiq_disable();
76
77 /*
78 * CPU0 has to stay ON (i.e in C1) until CPU1 is OFF state.
79 * This is necessary to honour hardware recommondation
80 * of triggeing all the possible low power modes once CPU1 is
81 * out of coherency and in OFF mode.
82 * Update dev->last_state so that governor stats reflects right
83 * data.
84 */
85 cpu1_state = pwrdm_read_pwrst(cpu1_pd);
86 if (cpu1_state != PWRDM_POWER_OFF) {
87 new_state_idx = drv->safe_state_index;
88 cx = cpuidle_get_statedata(&dev->states_usage[new_state_idx]);
89 }
90
91 if (index > 0)
92 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
93
94 /*
95 * Call idle CPU PM enter notifier chain so that
96 * VFP and per CPU interrupt context is saved.
97 */
98 if (cx->cpu_state == PWRDM_POWER_OFF)
99 cpu_pm_enter();
100
101 pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
102 omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
103
104 /*
105 * Call idle CPU cluster PM enter notifier chain
106 * to save GIC and wakeupgen context.
107 */
108 if ((cx->mpu_state == PWRDM_POWER_RET) &&
109 (cx->mpu_logic_state == PWRDM_POWER_OFF))
110 cpu_cluster_pm_enter();
111
112 omap4_enter_lowpower(dev->cpu, cx->cpu_state);
113
114 /*
115 * Call idle CPU PM exit notifier chain to restore
116 * VFP and per CPU IRQ context. Only CPU0 state is
117 * considered since CPU1 is managed by CPU hotplug.
118 */
119 if (pwrdm_read_prev_pwrst(cpu0_pd) == PWRDM_POWER_OFF)
120 cpu_pm_exit();
121
122 /*
123 * Call idle CPU cluster PM exit notifier chain
124 * to restore GIC and wakeupgen context.
125 */
126 if (omap4_mpuss_read_prev_context_state())
127 cpu_cluster_pm_exit();
128
129 if (index > 0)
130 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
131
132 getnstimeofday(&ts_postidle);
133 ts_idle = timespec_sub(ts_postidle, ts_preidle);
134
135 local_irq_enable();
136 local_fiq_enable();
137
138 idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \
139 USEC_PER_SEC;
140
141 /* Update cpuidle counters */
142 dev->last_residency = idle_time;
143
144 return index;
145}
146
147DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
148
149struct cpuidle_driver omap4_idle_driver = {
150 .name = "omap4_idle",
151 .owner = THIS_MODULE,
152};
153
154static inline void _fill_cstate(struct cpuidle_driver *drv,
155 int idx, const char *descr)
156{
157 struct cpuidle_state *state = &drv->states[idx];
158
159 state->exit_latency = cpuidle_params_table[idx].exit_latency;
160 state->target_residency = cpuidle_params_table[idx].target_residency;
161 state->flags = CPUIDLE_FLAG_TIME_VALID;
162 state->enter = omap4_enter_idle;
163 sprintf(state->name, "C%d", idx + 1);
164 strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
165}
166
167static inline struct omap4_idle_statedata *_fill_cstate_usage(
168 struct cpuidle_device *dev,
169 int idx)
170{
171 struct omap4_idle_statedata *cx = &omap4_idle_data[idx];
172 struct cpuidle_state_usage *state_usage = &dev->states_usage[idx];
173
174 cx->valid = cpuidle_params_table[idx].valid;
175 cpuidle_set_statedata(state_usage, cx);
176
177 return cx;
178}
179
180
181
182/**
183 * omap4_idle_init - Init routine for OMAP4 idle
184 *
185 * Registers the OMAP4 specific cpuidle driver to the cpuidle
186 * framework with the valid set of states.
187 */
188int __init omap4_idle_init(void)
189{
190 struct omap4_idle_statedata *cx;
191 struct cpuidle_device *dev;
192 struct cpuidle_driver *drv = &omap4_idle_driver;
193 unsigned int cpu_id = 0;
194
195 mpu_pd = pwrdm_lookup("mpu_pwrdm");
196 cpu0_pd = pwrdm_lookup("cpu0_pwrdm");
197 cpu1_pd = pwrdm_lookup("cpu1_pwrdm");
198 if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd))
199 return -ENODEV;
200
201
202 drv->safe_state_index = -1;
203 dev = &per_cpu(omap4_idle_dev, cpu_id);
204 dev->cpu = cpu_id;
205
206 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
207 _fill_cstate(drv, 0, "MPUSS ON");
208 drv->safe_state_index = 0;
209 cx = _fill_cstate_usage(dev, 0);
210 cx->valid = 1; /* C1 is always valid */
211 cx->cpu_state = PWRDM_POWER_ON;
212 cx->mpu_state = PWRDM_POWER_ON;
213 cx->mpu_logic_state = PWRDM_POWER_RET;
214
215 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
216 _fill_cstate(drv, 1, "MPUSS CSWR");
217 cx = _fill_cstate_usage(dev, 1);
218 cx->cpu_state = PWRDM_POWER_OFF;
219 cx->mpu_state = PWRDM_POWER_RET;
220 cx->mpu_logic_state = PWRDM_POWER_RET;
221
222 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
223 _fill_cstate(drv, 2, "MPUSS OSWR");
224 cx = _fill_cstate_usage(dev, 2);
225 cx->cpu_state = PWRDM_POWER_OFF;
226 cx->mpu_state = PWRDM_POWER_RET;
227 cx->mpu_logic_state = PWRDM_POWER_OFF;
228
229 drv->state_count = OMAP4_NUM_STATES;
230 cpuidle_register_driver(&omap4_idle_driver);
231
232 dev->state_count = OMAP4_NUM_STATES;
233 if (cpuidle_register_device(dev)) {
234 pr_err("%s: CPUidle register device failed\n", __func__);
235 return -EIO;
236 }
237
238 return 0;
239}
240#else
241int __init omap4_idle_init(void)
242{
243 return 0;
244}
245#endif /* CONFIG_CPU_IDLE */
diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h
new file mode 100644
index 000000000000..4fa72c7cc7cd
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/barriers.h
@@ -0,0 +1,31 @@
1/*
2 * OMAP memory barrier header.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 * Richard Woodruff <r-woodruff2@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __MACH_BARRIERS_H
23#define __MACH_BARRIERS_H
24
25extern void omap_bus_sync(void);
26
27#define rmb() dsb()
28#define wmb() do { dsb(); outer_sync(); omap_bus_sync(); } while (0)
29#define mb() wmb()
30
31#endif /* __MACH_BARRIERS_H */
diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h
new file mode 100644
index 000000000000..c90a43589abe
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/omap-secure.h
@@ -0,0 +1,57 @@
1/*
2 * omap-secure.h: OMAP Secure infrastructure header.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
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#ifndef OMAP_ARCH_OMAP_SECURE_H
12#define OMAP_ARCH_OMAP_SECURE_H
13
14/* Monitor error code */
15#define API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR 0xFFFFFFFE
16#define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF
17
18/* HAL API error codes */
19#define API_HAL_RET_VALUE_OK 0x00
20#define API_HAL_RET_VALUE_FAIL 0x01
21
22/* Secure HAL API flags */
23#define FLAG_START_CRITICAL 0x4
24#define FLAG_IRQFIQ_MASK 0x3
25#define FLAG_IRQ_ENABLE 0x2
26#define FLAG_FIQ_ENABLE 0x1
27#define NO_FLAG 0x0
28
29/* Maximum Secure memory storage size */
30#define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K)
31
32/* Secure low power HAL API index */
33#define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a
34#define OMAP4_HAL_SAVEHW_INDEX 0x1b
35#define OMAP4_HAL_SAVEALL_INDEX 0x1c
36#define OMAP4_HAL_SAVEGIC_INDEX 0x1d
37
38/* Secure Monitor mode APIs */
39#define OMAP4_MON_SCU_PWR_INDEX 0x108
40#define OMAP4_MON_L2X0_DBG_CTRL_INDEX 0x100
41#define OMAP4_MON_L2X0_CTRL_INDEX 0x102
42#define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109
43#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113
44
45/* Secure PPA(Primary Protected Application) APIs */
46#define OMAP4_PPA_L2_POR_INDEX 0x23
47#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
48
49#ifndef __ASSEMBLER__
50
51extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
52 u32 arg1, u32 arg2, u32 arg3, u32 arg4);
53extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
54extern phys_addr_t omap_secure_ram_mempool_base(void);
55
56#endif /* __ASSEMBLER__ */
57#endif /* OMAP_ARCH_OMAP_SECURE_H */
diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
new file mode 100644
index 000000000000..d79321b0f2a2
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
@@ -0,0 +1,39 @@
1/*
2 * OMAP WakeupGen header file
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
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#ifndef OMAP_ARCH_WAKEUPGEN_H
12#define OMAP_ARCH_WAKEUPGEN_H
13
14#define OMAP_WKG_CONTROL_0 0x00
15#define OMAP_WKG_ENB_A_0 0x10
16#define OMAP_WKG_ENB_B_0 0x14
17#define OMAP_WKG_ENB_C_0 0x18
18#define OMAP_WKG_ENB_D_0 0x1c
19#define OMAP_WKG_ENB_SECURE_A_0 0x20
20#define OMAP_WKG_ENB_SECURE_B_0 0x24
21#define OMAP_WKG_ENB_SECURE_C_0 0x28
22#define OMAP_WKG_ENB_SECURE_D_0 0x2c
23#define OMAP_WKG_ENB_A_1 0x410
24#define OMAP_WKG_ENB_B_1 0x414
25#define OMAP_WKG_ENB_C_1 0x418
26#define OMAP_WKG_ENB_D_1 0x41c
27#define OMAP_WKG_ENB_SECURE_A_1 0x420
28#define OMAP_WKG_ENB_SECURE_B_1 0x424
29#define OMAP_WKG_ENB_SECURE_C_1 0x428
30#define OMAP_WKG_ENB_SECURE_D_1 0x42c
31#define OMAP_AUX_CORE_BOOT_0 0x800
32#define OMAP_AUX_CORE_BOOT_1 0x804
33#define OMAP_PTMSYNCREQ_MASK 0xc00
34#define OMAP_PTMSYNCREQ_EN 0xc04
35#define OMAP_TIMESTAMPCYCLELO 0xc08
36#define OMAP_TIMESTAMPCYCLEHI 0xc0c
37
38extern int __init omap_wakeupgen_init(void);
39#endif
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 73d617f0dc4a..3f174d51f67f 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -254,6 +254,15 @@ static struct map_desc omap44xx_io_desc[] __initdata = {
254 .length = L4_EMU_44XX_SIZE, 254 .length = L4_EMU_44XX_SIZE,
255 .type = MT_DEVICE, 255 .type = MT_DEVICE,
256 }, 256 },
257#ifdef CONFIG_OMAP4_ERRATA_I688
258 {
259 .virtual = OMAP4_SRAM_VA,
260 .pfn = __phys_to_pfn(OMAP4_SRAM_PA),
261 .length = PAGE_SIZE,
262 .type = MT_MEMORY_SO,
263 },
264#endif
265
257}; 266};
258#endif 267#endif
259 268
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 655e9480eb98..e1cc75d1a57a 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -32,6 +32,8 @@
32#include <linux/debugfs.h> 32#include <linux/debugfs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35#include <linux/irq.h>
36#include <linux/interrupt.h>
35 37
36#include <asm/system.h> 38#include <asm/system.h>
37 39
@@ -39,6 +41,7 @@
39 41
40#include "control.h" 42#include "control.h"
41#include "mux.h" 43#include "mux.h"
44#include "prm.h"
42 45
43#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ 46#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
44#define OMAP_MUX_BASE_SZ 0x5ca 47#define OMAP_MUX_BASE_SZ 0x5ca
@@ -306,7 +309,8 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
306 pad->idle = bpad->idle; 309 pad->idle = bpad->idle;
307 pad->off = bpad->off; 310 pad->off = bpad->off;
308 311
309 if (pad->flags & OMAP_DEVICE_PAD_REMUX) 312 if (pad->flags &
313 (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP))
310 nr_pads_dynamic++; 314 nr_pads_dynamic++;
311 315
312 pr_debug("%s: Initialized %s\n", __func__, pad->name); 316 pr_debug("%s: Initialized %s\n", __func__, pad->name);
@@ -331,7 +335,8 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
331 for (i = 0; i < hmux->nr_pads; i++) { 335 for (i = 0; i < hmux->nr_pads; i++) {
332 struct omap_device_pad *pad = &hmux->pads[i]; 336 struct omap_device_pad *pad = &hmux->pads[i];
333 337
334 if (pad->flags & OMAP_DEVICE_PAD_REMUX) { 338 if (pad->flags &
339 (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) {
335 pr_debug("%s: pad %s tagged dynamic\n", 340 pr_debug("%s: pad %s tagged dynamic\n",
336 __func__, pad->name); 341 __func__, pad->name);
337 hmux->pads_dynamic[nr_pads_dynamic] = pad; 342 hmux->pads_dynamic[nr_pads_dynamic] = pad;
@@ -351,6 +356,78 @@ err1:
351 return NULL; 356 return NULL;
352} 357}
353 358
359/**
360 * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads
361 * @hmux: Pads for a hwmod
362 * @mpu_irqs: MPU irq array for a hwmod
363 *
364 * Scans the wakeup status of pads for a single hwmod. If an irq
365 * array is defined for this mux, the parser will call the registered
366 * ISRs for corresponding pads, otherwise the parser will stop at the
367 * first wakeup active pad and return. Returns true if there is a
368 * pending and non-served wakeup event for the mux, otherwise false.
369 */
370static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux,
371 struct omap_hwmod_irq_info *mpu_irqs)
372{
373 int i, irq;
374 unsigned int val;
375 u32 handled_irqs = 0;
376
377 for (i = 0; i < hmux->nr_pads_dynamic; i++) {
378 struct omap_device_pad *pad = hmux->pads_dynamic[i];
379
380 if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP) ||
381 !(pad->idle & OMAP_WAKEUP_EN))
382 continue;
383
384 val = omap_mux_read(pad->partition, pad->mux->reg_offset);
385 if (!(val & OMAP_WAKEUP_EVENT))
386 continue;
387
388 if (!hmux->irqs)
389 return true;
390
391 irq = hmux->irqs[i];
392 /* make sure we only handle each irq once */
393 if (handled_irqs & 1 << irq)
394 continue;
395
396 handled_irqs |= 1 << irq;
397
398 generic_handle_irq(mpu_irqs[irq].irq);
399 }
400
401 return false;
402}
403
404/**
405 * _omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod
406 *
407 * Checks a single hwmod for every wakeup capable pad to see if there is an
408 * active wakeup event. If this is the case, call the corresponding ISR.
409 */
410static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
411{
412 if (!oh->mux || !oh->mux->enabled)
413 return 0;
414 if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs))
415 generic_handle_irq(oh->mpu_irqs[0].irq);
416 return 0;
417}
418
419/**
420 * omap_hwmod_mux_handle_irq - Process pad wakeup irqs.
421 *
422 * Calls a function for each registered omap_hwmod to check
423 * pad wakeup statuses.
424 */
425static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused)
426{
427 omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL);
428 return IRQ_HANDLED;
429}
430
354/* Assumes the calling function takes care of locking */ 431/* Assumes the calling function takes care of locking */
355void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) 432void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
356{ 433{
@@ -715,6 +792,7 @@ static void __init omap_mux_free_names(struct omap_mux *m)
715static int __init omap_mux_late_init(void) 792static int __init omap_mux_late_init(void)
716{ 793{
717 struct omap_mux_partition *partition; 794 struct omap_mux_partition *partition;
795 int ret;
718 796
719 list_for_each_entry(partition, &mux_partitions, node) { 797 list_for_each_entry(partition, &mux_partitions, node) {
720 struct omap_mux_entry *e, *tmp; 798 struct omap_mux_entry *e, *tmp;
@@ -735,6 +813,13 @@ static int __init omap_mux_late_init(void)
735 } 813 }
736 } 814 }
737 815
816 ret = request_irq(omap_prcm_event_to_irq("io"),
817 omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
818 "hwmod_io", omap_mux_late_init);
819
820 if (ret)
821 pr_warning("mux: Failed to setup hwmod io irq %d\n", ret);
822
738 omap_mux_dbg_init(); 823 omap_mux_dbg_init();
739 824
740 return 0; 825 return 0;
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index 4ee6aeca885a..b13ef7ef5ef4 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -18,11 +18,6 @@
18#include <linux/linkage.h> 18#include <linux/linkage.h>
19#include <linux/init.h> 19#include <linux/init.h>
20 20
21/* Physical address needed since MMU not enabled yet on secondary core */
22#define OMAP4_AUX_CORE_BOOT1_PA 0x48281804
23
24 __INIT
25
26/* 21/*
27 * OMAP4 specific entry point for secondary CPU to jump from ROM 22 * OMAP4 specific entry point for secondary CPU to jump from ROM
28 * code. This routine also provides a holding flag into which 23 * code. This routine also provides a holding flag into which
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index e5a1c3f40a86..adbe4d8c7caf 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -22,6 +22,8 @@
22 22
23#include "common.h" 23#include "common.h"
24 24
25#include "powerdomain.h"
26
25int platform_cpu_kill(unsigned int cpu) 27int platform_cpu_kill(unsigned int cpu)
26{ 28{
27 return 1; 29 return 1;
@@ -33,6 +35,8 @@ int platform_cpu_kill(unsigned int cpu)
33 */ 35 */
34void platform_cpu_die(unsigned int cpu) 36void platform_cpu_die(unsigned int cpu)
35{ 37{
38 unsigned int this_cpu;
39
36 flush_cache_all(); 40 flush_cache_all();
37 dsb(); 41 dsb();
38 42
@@ -40,15 +44,15 @@ void platform_cpu_die(unsigned int cpu)
40 * we're ready for shutdown now, so do it 44 * we're ready for shutdown now, so do it
41 */ 45 */
42 if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) 46 if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
43 printk(KERN_CRIT "Secure clear status failed\n"); 47 pr_err("Secure clear status failed\n");
44 48
45 for (;;) { 49 for (;;) {
46 /* 50 /*
47 * Execute WFI 51 * Enter into low power state
48 */ 52 */
49 do_wfi(); 53 omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
50 54 this_cpu = smp_processor_id();
51 if (omap_read_auxcoreboot0() == cpu) { 55 if (omap_read_auxcoreboot0() == this_cpu) {
52 /* 56 /*
53 * OK, proper wakeup, we're done 57 * OK, proper wakeup, we're done
54 */ 58 */
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
new file mode 100644
index 000000000000..1d5d01056558
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -0,0 +1,398 @@
1/*
2 * OMAP MPUSS low power code
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 * OMAP4430 MPUSS mainly consists of dual Cortex-A9 with per-CPU
8 * Local timer and Watchdog, GIC, SCU, PL310 L2 cache controller,
9 * CPU0 and CPU1 LPRM modules.
10 * CPU0, CPU1 and MPUSS each have there own power domain and
11 * hence multiple low power combinations of MPUSS are possible.
12 *
13 * The CPU0 and CPU1 can't support Closed switch Retention (CSWR)
14 * because the mode is not supported by hw constraints of dormant
15 * mode. While waking up from the dormant mode, a reset signal
16 * to the Cortex-A9 processor must be asserted by the external
17 * power controller.
18 *
19 * With architectural inputs and hardware recommendations, only
20 * below modes are supported from power gain vs latency point of view.
21 *
22 * CPU0 CPU1 MPUSS
23 * ----------------------------------------------
24 * ON ON ON
25 * ON(Inactive) OFF ON(Inactive)
26 * OFF OFF CSWR
27 * OFF OFF OSWR
28 * OFF OFF OFF(Device OFF *TBD)
29 * ----------------------------------------------
30 *
31 * Note: CPU0 is the master core and it is the last CPU to go down
32 * and first to wake-up when MPUSS low power states are excercised
33 *
34 *
35 * This program is free software; you can redistribute it and/or modify
36 * it under the terms of the GNU General Public License version 2 as
37 * published by the Free Software Foundation.
38 */
39
40#include <linux/kernel.h>
41#include <linux/io.h>
42#include <linux/errno.h>
43#include <linux/linkage.h>
44#include <linux/smp.h>
45
46#include <asm/cacheflush.h>
47#include <asm/tlbflush.h>
48#include <asm/smp_scu.h>
49#include <asm/system.h>
50#include <asm/pgalloc.h>
51#include <asm/suspend.h>
52#include <asm/hardware/cache-l2x0.h>
53
54#include <plat/omap44xx.h>
55
56#include "common.h"
57#include "omap4-sar-layout.h"
58#include "pm.h"
59#include "prcm_mpu44xx.h"
60#include "prminst44xx.h"
61#include "prcm44xx.h"
62#include "prm44xx.h"
63#include "prm-regbits-44xx.h"
64
65#ifdef CONFIG_SMP
66
67struct omap4_cpu_pm_info {
68 struct powerdomain *pwrdm;
69 void __iomem *scu_sar_addr;
70 void __iomem *wkup_sar_addr;
71 void __iomem *l2x0_sar_addr;
72};
73
74static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
75static struct powerdomain *mpuss_pd;
76static void __iomem *sar_base;
77
78/*
79 * Program the wakeup routine address for the CPU0 and CPU1
80 * used for OFF or DORMANT wakeup.
81 */
82static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
83{
84 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
85
86 __raw_writel(addr, pm_info->wkup_sar_addr);
87}
88
89/*
90 * Set the CPUx powerdomain's previous power state
91 */
92static inline void set_cpu_next_pwrst(unsigned int cpu_id,
93 unsigned int power_state)
94{
95 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
96
97 pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
98}
99
100/*
101 * Read CPU's previous power state
102 */
103static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id)
104{
105 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
106
107 return pwrdm_read_prev_pwrst(pm_info->pwrdm);
108}
109
110/*
111 * Clear the CPUx powerdomain's previous power state
112 */
113static inline void clear_cpu_prev_pwrst(unsigned int cpu_id)
114{
115 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
116
117 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
118}
119
120/*
121 * Store the SCU power status value to scratchpad memory
122 */
123static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
124{
125 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
126 u32 scu_pwr_st;
127
128 switch (cpu_state) {
129 case PWRDM_POWER_RET:
130 scu_pwr_st = SCU_PM_DORMANT;
131 break;
132 case PWRDM_POWER_OFF:
133 scu_pwr_st = SCU_PM_POWEROFF;
134 break;
135 case PWRDM_POWER_ON:
136 case PWRDM_POWER_INACTIVE:
137 default:
138 scu_pwr_st = SCU_PM_NORMAL;
139 break;
140 }
141
142 __raw_writel(scu_pwr_st, pm_info->scu_sar_addr);
143}
144
145/* Helper functions for MPUSS OSWR */
146static inline void mpuss_clear_prev_logic_pwrst(void)
147{
148 u32 reg;
149
150 reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
151 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
152 omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION,
153 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
154}
155
156static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
157{
158 u32 reg;
159
160 if (cpu_id) {
161 reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST,
162 OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
163 omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST,
164 OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
165 } else {
166 reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST,
167 OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
168 omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST,
169 OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
170 }
171}
172
173/**
174 * omap4_mpuss_read_prev_context_state:
175 * Function returns the MPUSS previous context state
176 */
177u32 omap4_mpuss_read_prev_context_state(void)
178{
179 u32 reg;
180
181 reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
182 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
183 reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
184 return reg;
185}
186
187/*
188 * Store the CPU cluster state for L2X0 low power operations.
189 */
190static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state)
191{
192 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
193
194 __raw_writel(save_state, pm_info->l2x0_sar_addr);
195}
196
197/*
198 * Save the L2X0 AUXCTRL and POR value to SAR memory. Its used to
199 * in every restore MPUSS OFF path.
200 */
201#ifdef CONFIG_CACHE_L2X0
202static void save_l2x0_context(void)
203{
204 u32 val;
205 void __iomem *l2x0_base = omap4_get_l2cache_base();
206
207 val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
208 __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
209 val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
210 __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
211}
212#else
213static void save_l2x0_context(void)
214{}
215#endif
216
217/**
218 * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
219 * The purpose of this function is to manage low power programming
220 * of OMAP4 MPUSS subsystem
221 * @cpu : CPU ID
222 * @power_state: Low power state.
223 *
224 * MPUSS states for the context save:
225 * save_state =
226 * 0 - Nothing lost and no need to save: MPUSS INACTIVE
227 * 1 - CPUx L1 and logic lost: MPUSS CSWR
228 * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
229 * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
230 */
231int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
232{
233 unsigned int save_state = 0;
234 unsigned int wakeup_cpu;
235
236 if (omap_rev() == OMAP4430_REV_ES1_0)
237 return -ENXIO;
238
239 switch (power_state) {
240 case PWRDM_POWER_ON:
241 case PWRDM_POWER_INACTIVE:
242 save_state = 0;
243 break;
244 case PWRDM_POWER_OFF:
245 save_state = 1;
246 break;
247 case PWRDM_POWER_RET:
248 default:
249 /*
250 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
251 * doesn't make much scense, since logic is lost and $L1
252 * needs to be cleaned because of coherency. This makes
253 * CPUx OSWR equivalent to CPUX OFF and hence not supported
254 */
255 WARN_ON(1);
256 return -ENXIO;
257 }
258
259 pwrdm_pre_transition();
260
261 /*
262 * Check MPUSS next state and save interrupt controller if needed.
263 * In MPUSS OSWR or device OFF, interrupt controller contest is lost.
264 */
265 mpuss_clear_prev_logic_pwrst();
266 pwrdm_clear_all_prev_pwrst(mpuss_pd);
267 if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
268 (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
269 save_state = 2;
270
271 clear_cpu_prev_pwrst(cpu);
272 cpu_clear_prev_logic_pwrst(cpu);
273 set_cpu_next_pwrst(cpu, power_state);
274 set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
275 scu_pwrst_prepare(cpu, power_state);
276 l2x0_pwrst_prepare(cpu, save_state);
277
278 /*
279 * Call low level function with targeted low power state.
280 */
281 cpu_suspend(save_state, omap4_finish_suspend);
282
283 /*
284 * Restore the CPUx power state to ON otherwise CPUx
285 * power domain can transitions to programmed low power
286 * state while doing WFI outside the low powe code. On
287 * secure devices, CPUx does WFI which can result in
288 * domain transition
289 */
290 wakeup_cpu = smp_processor_id();
291 set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
292
293 pwrdm_post_transition();
294
295 return 0;
296}
297
298/**
299 * omap4_hotplug_cpu: OMAP4 CPU hotplug entry
300 * @cpu : CPU ID
301 * @power_state: CPU low power state.
302 */
303int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
304{
305 unsigned int cpu_state = 0;
306
307 if (omap_rev() == OMAP4430_REV_ES1_0)
308 return -ENXIO;
309
310 if (power_state == PWRDM_POWER_OFF)
311 cpu_state = 1;
312
313 clear_cpu_prev_pwrst(cpu);
314 set_cpu_next_pwrst(cpu, power_state);
315 set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup));
316 scu_pwrst_prepare(cpu, power_state);
317
318 /*
319 * CPU never retuns back if targetted power state is OFF mode.
320 * CPU ONLINE follows normal CPU ONLINE ptah via
321 * omap_secondary_startup().
322 */
323 omap4_finish_suspend(cpu_state);
324
325 set_cpu_next_pwrst(cpu, PWRDM_POWER_ON);
326 return 0;
327}
328
329
330/*
331 * Initialise OMAP4 MPUSS
332 */
333int __init omap4_mpuss_init(void)
334{
335 struct omap4_cpu_pm_info *pm_info;
336
337 if (omap_rev() == OMAP4430_REV_ES1_0) {
338 WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
339 return -ENODEV;
340 }
341
342 sar_base = omap4_get_sar_ram_base();
343
344 /* Initilaise per CPU PM information */
345 pm_info = &per_cpu(omap4_pm_info, 0x0);
346 pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
347 pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
348 pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
349 pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
350 if (!pm_info->pwrdm) {
351 pr_err("Lookup failed for CPU0 pwrdm\n");
352 return -ENODEV;
353 }
354
355 /* Clear CPU previous power domain state */
356 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
357 cpu_clear_prev_logic_pwrst(0);
358
359 /* Initialise CPU0 power domain state to ON */
360 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
361
362 pm_info = &per_cpu(omap4_pm_info, 0x1);
363 pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
364 pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
365 pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
366 pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
367 if (!pm_info->pwrdm) {
368 pr_err("Lookup failed for CPU1 pwrdm\n");
369 return -ENODEV;
370 }
371
372 /* Clear CPU previous power domain state */
373 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
374 cpu_clear_prev_logic_pwrst(1);
375
376 /* Initialise CPU1 power domain state to ON */
377 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
378
379 mpuss_pd = pwrdm_lookup("mpu_pwrdm");
380 if (!mpuss_pd) {
381 pr_err("Failed to lookup MPUSS power domain\n");
382 return -ENODEV;
383 }
384 pwrdm_clear_all_prev_pwrst(mpuss_pd);
385 mpuss_clear_prev_logic_pwrst();
386
387 /* Save device type on scratchpad for low level code to use */
388 if (omap_type() != OMAP2_DEVICE_TYPE_GP)
389 __raw_writel(1, sar_base + OMAP_TYPE_OFFSET);
390 else
391 __raw_writel(0, sar_base + OMAP_TYPE_OFFSET);
392
393 save_l2x0_context();
394
395 return 0;
396}
397
398#endif
diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c
new file mode 100644
index 000000000000..69f3c72d959b
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-secure.c
@@ -0,0 +1,81 @@
1/*
2 * OMAP Secure API infrastructure.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 *
8 * This program is free software,you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/memblock.h>
17
18#include <asm/cacheflush.h>
19
20#include <mach/omap-secure.h>
21
22static phys_addr_t omap_secure_memblock_base;
23
24/**
25 * omap_sec_dispatcher: Routine to dispatch low power secure
26 * service routines
27 * @idx: The HAL API index
28 * @flag: The flag indicating criticality of operation
29 * @nargs: Number of valid arguments out of four.
30 * @arg1, arg2, arg3 args4: Parameters passed to secure API
31 *
32 * Return the non-zero error value on failure.
33 */
34u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
35 u32 arg3, u32 arg4)
36{
37 u32 ret;
38 u32 param[5];
39
40 param[0] = nargs;
41 param[1] = arg1;
42 param[2] = arg2;
43 param[3] = arg3;
44 param[4] = arg4;
45
46 /*
47 * Secure API needs physical address
48 * pointer for the parameters
49 */
50 flush_cache_all();
51 outer_clean_range(__pa(param), __pa(param + 5));
52 ret = omap_smc2(idx, flag, __pa(param));
53
54 return ret;
55}
56
57/* Allocate the memory to save secure ram */
58int __init omap_secure_ram_reserve_memblock(void)
59{
60 phys_addr_t paddr;
61 u32 size = OMAP_SECURE_RAM_STORAGE;
62
63 size = ALIGN(size, SZ_1M);
64 paddr = memblock_alloc(size, SZ_1M);
65 if (!paddr) {
66 pr_err("%s: failed to reserve %x bytes\n",
67 __func__, size);
68 return -ENOMEM;
69 }
70 memblock_free(paddr, size);
71 memblock_remove(paddr, size);
72
73 omap_secure_memblock_base = paddr;
74
75 return 0;
76}
77
78phys_addr_t omap_secure_ram_mempool_base(void)
79{
80 return omap_secure_memblock_base;
81}
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap-smc.S
index e69d37d95204..f6441c13cd8c 100644
--- a/arch/arm/mach-omap2/omap44xx-smc.S
+++ b/arch/arm/mach-omap2/omap-smc.S
@@ -31,6 +31,29 @@ ENTRY(omap_smc1)
31 ldmfd sp!, {r2-r12, pc} 31 ldmfd sp!, {r2-r12, pc}
32ENDPROC(omap_smc1) 32ENDPROC(omap_smc1)
33 33
34/**
35 * u32 omap_smc2(u32 id, u32 falg, u32 pargs)
36 * Low level common routine for secure HAL and PPA APIs.
37 * @id: Application ID of HAL APIs
38 * @flag: Flag to indicate the criticality of operation
39 * @pargs: Physical address of parameter list starting
40 * with number of parametrs
41 */
42ENTRY(omap_smc2)
43 stmfd sp!, {r4-r12, lr}
44 mov r3, r2
45 mov r2, r1
46 mov r1, #0x0 @ Process ID
47 mov r6, #0xff
48 mov r12, #0x00 @ Secure Service ID
49 mov r7, #0
50 mcr p15, 0, r7, c7, c5, 6
51 dsb
52 dmb
53 smc #0
54 ldmfd sp!, {r4-r12, pc}
55ENDPROC(omap_smc2)
56
34ENTRY(omap_modify_auxcoreboot0) 57ENTRY(omap_modify_auxcoreboot0)
35 stmfd sp!, {r1-r12, lr} 58 stmfd sp!, {r1-r12, lr}
36 ldr r12, =0x104 59 ldr r12, =0x104
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index e99bc6cd4714..c1bf3ef0ba02 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -24,17 +24,37 @@
24#include <asm/hardware/gic.h> 24#include <asm/hardware/gic.h>
25#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <mach/omap-secure.h>
27 28
28#include "common.h" 29#include "common.h"
29 30
31#include "clockdomain.h"
32
30/* SCU base address */ 33/* SCU base address */
31static void __iomem *scu_base; 34static void __iomem *scu_base;
32 35
33static DEFINE_SPINLOCK(boot_lock); 36static DEFINE_SPINLOCK(boot_lock);
34 37
38void __iomem *omap4_get_scu_base(void)
39{
40 return scu_base;
41}
42
35void __cpuinit platform_secondary_init(unsigned int cpu) 43void __cpuinit platform_secondary_init(unsigned int cpu)
36{ 44{
37 /* 45 /*
46 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
47 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
48 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
49 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
50 * OMAP443X GP devices- SMP bit isn't accessible.
51 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
52 */
53 if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
54 omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
55 4, 0, 0, 0, 0, 0);
56
57 /*
38 * If any interrupts are already enabled for the primary 58 * If any interrupts are already enabled for the primary
39 * core (e.g. timer irq), then they will not have been enabled 59 * core (e.g. timer irq), then they will not have been enabled
40 * for us: do so 60 * for us: do so
@@ -50,6 +70,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
50 70
51int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 71int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
52{ 72{
73 static struct clockdomain *cpu1_clkdm;
74 static bool booted;
53 /* 75 /*
54 * Set synchronisation state between this boot processor 76 * Set synchronisation state between this boot processor
55 * and the secondary one 77 * and the secondary one
@@ -65,6 +87,29 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
65 omap_modify_auxcoreboot0(0x200, 0xfffffdff); 87 omap_modify_auxcoreboot0(0x200, 0xfffffdff);
66 flush_cache_all(); 88 flush_cache_all();
67 smp_wmb(); 89 smp_wmb();
90
91 if (!cpu1_clkdm)
92 cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
93
94 /*
95 * The SGI(Software Generated Interrupts) are not wakeup capable
96 * from low power states. This is known limitation on OMAP4 and
97 * needs to be worked around by using software forced clockdomain
98 * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to
99 * software force wakeup. The clockdomain is then put back to
100 * hardware supervised mode.
101 * More details can be found in OMAP4430 TRM - Version J
102 * Section :
103 * 4.3.4.2 Power States of CPU0 and CPU1
104 */
105 if (booted) {
106 clkdm_wakeup(cpu1_clkdm);
107 clkdm_allow_idle(cpu1_clkdm);
108 } else {
109 dsb_sev();
110 booted = true;
111 }
112
68 gic_raise_softirq(cpumask_of(cpu), 1); 113 gic_raise_softirq(cpumask_of(cpu), 1);
69 114
70 /* 115 /*
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
new file mode 100644
index 000000000000..d3d8971d7f30
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -0,0 +1,389 @@
1/*
2 * OMAP WakeupGen Source file
3 *
4 * OMAP WakeupGen is the interrupt controller extension used along
5 * with ARM GIC to wake the CPU out from low power states on
6 * external interrupts. It is responsible for generating wakeup
7 * event from the incoming interrupts and enable bits. It is
8 * implemented in MPU always ON power domain. During normal operation,
9 * WakeupGen delivers external interrupts directly to the GIC.
10 *
11 * Copyright (C) 2011 Texas Instruments, Inc.
12 * Santosh Shilimkar <santosh.shilimkar@ti.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/io.h>
22#include <linux/irq.h>
23#include <linux/platform_device.h>
24#include <linux/cpu.h>
25#include <linux/notifier.h>
26#include <linux/cpu_pm.h>
27
28#include <asm/hardware/gic.h>
29
30#include <mach/omap-wakeupgen.h>
31#include <mach/omap-secure.h>
32
33#include "omap4-sar-layout.h"
34#include "common.h"
35
36#define NR_REG_BANKS 4
37#define MAX_IRQS 128
38#define WKG_MASK_ALL 0x00000000
39#define WKG_UNMASK_ALL 0xffffffff
40#define CPU_ENA_OFFSET 0x400
41#define CPU0_ID 0x0
42#define CPU1_ID 0x1
43
44static void __iomem *wakeupgen_base;
45static void __iomem *sar_base;
46static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks);
47static DEFINE_SPINLOCK(wakeupgen_lock);
48static unsigned int irq_target_cpu[NR_IRQS];
49
50/*
51 * Static helper functions.
52 */
53static inline u32 wakeupgen_readl(u8 idx, u32 cpu)
54{
55 return __raw_readl(wakeupgen_base + OMAP_WKG_ENB_A_0 +
56 (cpu * CPU_ENA_OFFSET) + (idx * 4));
57}
58
59static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu)
60{
61 __raw_writel(val, wakeupgen_base + OMAP_WKG_ENB_A_0 +
62 (cpu * CPU_ENA_OFFSET) + (idx * 4));
63}
64
65static inline void sar_writel(u32 val, u32 offset, u8 idx)
66{
67 __raw_writel(val, sar_base + offset + (idx * 4));
68}
69
70static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)
71{
72 u8 i;
73
74 for (i = 0; i < NR_REG_BANKS; i++)
75 wakeupgen_writel(reg, i, cpu);
76}
77
78static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index)
79{
80 unsigned int spi_irq;
81
82 /*
83 * PPIs and SGIs are not supported.
84 */
85 if (irq < OMAP44XX_IRQ_GIC_START)
86 return -EINVAL;
87
88 /*
89 * Subtract the GIC offset.
90 */
91 spi_irq = irq - OMAP44XX_IRQ_GIC_START;
92 if (spi_irq > MAX_IRQS) {
93 pr_err("omap wakeupGen: Invalid IRQ%d\n", irq);
94 return -EINVAL;
95 }
96
97 /*
98 * Each WakeupGen register controls 32 interrupt.
99 * i.e. 1 bit per SPI IRQ
100 */
101 *reg_index = spi_irq >> 5;
102 *bit_posn = spi_irq %= 32;
103
104 return 0;
105}
106
107static void _wakeupgen_clear(unsigned int irq, unsigned int cpu)
108{
109 u32 val, bit_number;
110 u8 i;
111
112 if (_wakeupgen_get_irq_info(irq, &bit_number, &i))
113 return;
114
115 val = wakeupgen_readl(i, cpu);
116 val &= ~BIT(bit_number);
117 wakeupgen_writel(val, i, cpu);
118}
119
120static void _wakeupgen_set(unsigned int irq, unsigned int cpu)
121{
122 u32 val, bit_number;
123 u8 i;
124
125 if (_wakeupgen_get_irq_info(irq, &bit_number, &i))
126 return;
127
128 val = wakeupgen_readl(i, cpu);
129 val |= BIT(bit_number);
130 wakeupgen_writel(val, i, cpu);
131}
132
133static void _wakeupgen_save_masks(unsigned int cpu)
134{
135 u8 i;
136
137 for (i = 0; i < NR_REG_BANKS; i++)
138 per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu);
139}
140
141static void _wakeupgen_restore_masks(unsigned int cpu)
142{
143 u8 i;
144
145 for (i = 0; i < NR_REG_BANKS; i++)
146 wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu);
147}
148
149/*
150 * Architecture specific Mask extension
151 */
152static void wakeupgen_mask(struct irq_data *d)
153{
154 unsigned long flags;
155
156 spin_lock_irqsave(&wakeupgen_lock, flags);
157 _wakeupgen_clear(d->irq, irq_target_cpu[d->irq]);
158 spin_unlock_irqrestore(&wakeupgen_lock, flags);
159}
160
161/*
162 * Architecture specific Unmask extension
163 */
164static void wakeupgen_unmask(struct irq_data *d)
165{
166 unsigned long flags;
167
168 spin_lock_irqsave(&wakeupgen_lock, flags);
169 _wakeupgen_set(d->irq, irq_target_cpu[d->irq]);
170 spin_unlock_irqrestore(&wakeupgen_lock, flags);
171}
172
173/*
174 * Mask or unmask all interrupts on given CPU.
175 * 0 = Mask all interrupts on the 'cpu'
176 * 1 = Unmask all interrupts on the 'cpu'
177 * Ensure that the initial mask is maintained. This is faster than
178 * iterating through GIC registers to arrive at the correct masks.
179 */
180static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)
181{
182 unsigned long flags;
183
184 spin_lock_irqsave(&wakeupgen_lock, flags);
185 if (set) {
186 _wakeupgen_save_masks(cpu);
187 _wakeupgen_set_all(cpu, WKG_MASK_ALL);
188 } else {
189 _wakeupgen_set_all(cpu, WKG_UNMASK_ALL);
190 _wakeupgen_restore_masks(cpu);
191 }
192 spin_unlock_irqrestore(&wakeupgen_lock, flags);
193}
194
195#ifdef CONFIG_CPU_PM
196/*
197 * Save WakeupGen interrupt context in SAR BANK3. Restore is done by
198 * ROM code. WakeupGen IP is integrated along with GIC to manage the
199 * interrupt wakeups from CPU low power states. It manages
200 * masking/unmasking of Shared peripheral interrupts(SPI). So the
201 * interrupt enable/disable control should be in sync and consistent
202 * at WakeupGen and GIC so that interrupts are not lost.
203 */
204static void irq_save_context(void)
205{
206 u32 i, val;
207
208 if (omap_rev() == OMAP4430_REV_ES1_0)
209 return;
210
211 if (!sar_base)
212 sar_base = omap4_get_sar_ram_base();
213
214 for (i = 0; i < NR_REG_BANKS; i++) {
215 /* Save the CPUx interrupt mask for IRQ 0 to 127 */
216 val = wakeupgen_readl(i, 0);
217 sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i);
218 val = wakeupgen_readl(i, 1);
219 sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i);
220
221 /*
222 * Disable the secure interrupts for CPUx. The restore
223 * code blindly restores secure and non-secure interrupt
224 * masks from SAR RAM. Secure interrupts are not suppose
225 * to be enabled from HLOS. So overwrite the SAR location
226 * so that the secure interrupt remains disabled.
227 */
228 sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i);
229 sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i);
230 }
231
232 /* Save AuxBoot* registers */
233 val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
234 __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET);
235 val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
236 __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET);
237
238 /* Save SyncReq generation logic */
239 val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
240 __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET);
241 val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
242 __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET);
243
244 /* Save SyncReq generation logic */
245 val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_MASK);
246 __raw_writel(val, sar_base + PTMSYNCREQ_MASK_OFFSET);
247 val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_EN);
248 __raw_writel(val, sar_base + PTMSYNCREQ_EN_OFFSET);
249
250 /* Set the Backup Bit Mask status */
251 val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
252 val |= SAR_BACKUP_STATUS_WAKEUPGEN;
253 __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
254}
255
256/*
257 * Clear WakeupGen SAR backup status.
258 */
259void irq_sar_clear(void)
260{
261 u32 val;
262 val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
263 val &= ~SAR_BACKUP_STATUS_WAKEUPGEN;
264 __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
265}
266
267/*
268 * Save GIC and Wakeupgen interrupt context using secure API
269 * for HS/EMU devices.
270 */
271static void irq_save_secure_context(void)
272{
273 u32 ret;
274 ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
275 FLAG_START_CRITICAL,
276 0, 0, 0, 0, 0);
277 if (ret != API_HAL_RET_VALUE_OK)
278 pr_err("GIC and Wakeupgen context save failed\n");
279}
280#endif
281
282#ifdef CONFIG_HOTPLUG_CPU
283static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self,
284 unsigned long action, void *hcpu)
285{
286 unsigned int cpu = (unsigned int)hcpu;
287
288 switch (action) {
289 case CPU_ONLINE:
290 wakeupgen_irqmask_all(cpu, 0);
291 break;
292 case CPU_DEAD:
293 wakeupgen_irqmask_all(cpu, 1);
294 break;
295 }
296 return NOTIFY_OK;
297}
298
299static struct notifier_block __refdata irq_hotplug_notifier = {
300 .notifier_call = irq_cpu_hotplug_notify,
301};
302
303static void __init irq_hotplug_init(void)
304{
305 register_hotcpu_notifier(&irq_hotplug_notifier);
306}
307#else
308static void __init irq_hotplug_init(void)
309{}
310#endif
311
312#ifdef CONFIG_CPU_PM
313static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v)
314{
315 switch (cmd) {
316 case CPU_CLUSTER_PM_ENTER:
317 if (omap_type() == OMAP2_DEVICE_TYPE_GP)
318 irq_save_context();
319 else
320 irq_save_secure_context();
321 break;
322 case CPU_CLUSTER_PM_EXIT:
323 if (omap_type() == OMAP2_DEVICE_TYPE_GP)
324 irq_sar_clear();
325 break;
326 }
327 return NOTIFY_OK;
328}
329
330static struct notifier_block irq_notifier_block = {
331 .notifier_call = irq_notifier,
332};
333
334static void __init irq_pm_init(void)
335{
336 cpu_pm_register_notifier(&irq_notifier_block);
337}
338#else
339static void __init irq_pm_init(void)
340{}
341#endif
342
343/*
344 * Initialise the wakeupgen module.
345 */
346int __init omap_wakeupgen_init(void)
347{
348 int i;
349 unsigned int boot_cpu = smp_processor_id();
350
351 /* Not supported on OMAP4 ES1.0 silicon */
352 if (omap_rev() == OMAP4430_REV_ES1_0) {
353 WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n");
354 return -EPERM;
355 }
356
357 /* Static mapping, never released */
358 wakeupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K);
359 if (WARN_ON(!wakeupgen_base))
360 return -ENOMEM;
361
362 /* Clear all IRQ bitmasks at wakeupGen level */
363 for (i = 0; i < NR_REG_BANKS; i++) {
364 wakeupgen_writel(0, i, CPU0_ID);
365 wakeupgen_writel(0, i, CPU1_ID);
366 }
367
368 /*
369 * Override GIC architecture specific functions to add
370 * OMAP WakeupGen interrupt controller along with GIC
371 */
372 gic_arch_extn.irq_mask = wakeupgen_mask;
373 gic_arch_extn.irq_unmask = wakeupgen_unmask;
374 gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE;
375
376 /*
377 * FIXME: Add support to set_smp_affinity() once the core
378 * GIC code has necessary hooks in place.
379 */
380
381 /* Associate all the IRQs to boot CPU like GIC init does. */
382 for (i = 0; i < NR_IRQS; i++)
383 irq_target_cpu[i] = boot_cpu;
384
385 irq_hotplug_init();
386 irq_pm_init();
387
388 return 0;
389}
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index beecfdd56ea3..bc16c818c6b7 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -15,18 +15,73 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/memblock.h>
18 19
19#include <asm/hardware/gic.h> 20#include <asm/hardware/gic.h>
20#include <asm/hardware/cache-l2x0.h> 21#include <asm/hardware/cache-l2x0.h>
22#include <asm/mach/map.h>
21 23
22#include <plat/irqs.h> 24#include <plat/irqs.h>
25#include <plat/sram.h>
23 26
24#include <mach/hardware.h> 27#include <mach/hardware.h>
28#include <mach/omap-wakeupgen.h>
25 29
26#include "common.h" 30#include "common.h"
31#include "omap4-sar-layout.h"
27 32
28#ifdef CONFIG_CACHE_L2X0 33#ifdef CONFIG_CACHE_L2X0
29void __iomem *l2cache_base; 34static void __iomem *l2cache_base;
35#endif
36
37static void __iomem *sar_ram_base;
38
39#ifdef CONFIG_OMAP4_ERRATA_I688
40/* Used to implement memory barrier on DRAM path */
41#define OMAP4_DRAM_BARRIER_VA 0xfe600000
42
43void __iomem *dram_sync, *sram_sync;
44
45void omap_bus_sync(void)
46{
47 if (dram_sync && sram_sync) {
48 writel_relaxed(readl_relaxed(dram_sync), dram_sync);
49 writel_relaxed(readl_relaxed(sram_sync), sram_sync);
50 isb();
51 }
52}
53
54static int __init omap_barriers_init(void)
55{
56 struct map_desc dram_io_desc[1];
57 phys_addr_t paddr;
58 u32 size;
59
60 if (!cpu_is_omap44xx())
61 return -ENODEV;
62
63 size = ALIGN(PAGE_SIZE, SZ_1M);
64 paddr = memblock_alloc(size, SZ_1M);
65 if (!paddr) {
66 pr_err("%s: failed to reserve 4 Kbytes\n", __func__);
67 return -ENOMEM;
68 }
69 memblock_free(paddr, size);
70 memblock_remove(paddr, size);
71 dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
72 dram_io_desc[0].pfn = __phys_to_pfn(paddr);
73 dram_io_desc[0].length = size;
74 dram_io_desc[0].type = MT_MEMORY_SO;
75 iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
76 dram_sync = (void __iomem *) dram_io_desc[0].virtual;
77 sram_sync = (void __iomem *) OMAP4_SRAM_VA;
78
79 pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
80 (long long) paddr, dram_io_desc[0].virtual);
81
82 return 0;
83}
84core_initcall(omap_barriers_init);
30#endif 85#endif
31 86
32void __init gic_init_irq(void) 87void __init gic_init_irq(void)
@@ -42,11 +97,18 @@ void __init gic_init_irq(void)
42 omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); 97 omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
43 BUG_ON(!omap_irq_base); 98 BUG_ON(!omap_irq_base);
44 99
100 omap_wakeupgen_init();
101
45 gic_init(0, 29, gic_dist_base_addr, omap_irq_base); 102 gic_init(0, 29, gic_dist_base_addr, omap_irq_base);
46} 103}
47 104
48#ifdef CONFIG_CACHE_L2X0 105#ifdef CONFIG_CACHE_L2X0
49 106
107void __iomem *omap4_get_l2cache_base(void)
108{
109 return l2cache_base;
110}
111
50static void omap4_l2x0_disable(void) 112static void omap4_l2x0_disable(void)
51{ 113{
52 /* Disable PL310 L2 Cache controller */ 114 /* Disable PL310 L2 Cache controller */
@@ -72,7 +134,8 @@ static int __init omap_l2_cache_init(void)
72 134
73 /* Static mapping, never released */ 135 /* Static mapping, never released */
74 l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); 136 l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
75 BUG_ON(!l2cache_base); 137 if (WARN_ON(!l2cache_base))
138 return -ENOMEM;
76 139
77 /* 140 /*
78 * 16-way associativity, parity disabled 141 * 16-way associativity, parity disabled
@@ -112,3 +175,30 @@ static int __init omap_l2_cache_init(void)
112} 175}
113early_initcall(omap_l2_cache_init); 176early_initcall(omap_l2_cache_init);
114#endif 177#endif
178
179void __iomem *omap4_get_sar_ram_base(void)
180{
181 return sar_ram_base;
182}
183
184/*
185 * SAR RAM used to save and restore the HW
186 * context in low power modes
187 */
188static int __init omap4_sar_ram_init(void)
189{
190 /*
191 * To avoid code running on other OMAPs in
192 * multi-omap builds
193 */
194 if (!cpu_is_omap44xx())
195 return -ENOMEM;
196
197 /* Static mapping, never released */
198 sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
199 if (WARN_ON(!sar_ram_base))
200 return -ENOMEM;
201
202 return 0;
203}
204early_initcall(omap4_sar_ram_init);
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
new file mode 100644
index 000000000000..fe5b545ad443
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -0,0 +1,50 @@
1/*
2 * omap4-sar-layout.h: OMAP4 SAR RAM layout header file
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
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#ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H
12#define OMAP_ARCH_OMAP4_SAR_LAYOUT_H
13
14/*
15 * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE
16 */
17#define SAR_BANK1_OFFSET 0x0000
18#define SAR_BANK2_OFFSET 0x1000
19#define SAR_BANK3_OFFSET 0x2000
20#define SAR_BANK4_OFFSET 0x3000
21
22/* Scratch pad memory offsets from SAR_BANK1 */
23#define SCU_OFFSET0 0xd00
24#define SCU_OFFSET1 0xd04
25#define OMAP_TYPE_OFFSET 0xd10
26#define L2X0_SAVE_OFFSET0 0xd14
27#define L2X0_SAVE_OFFSET1 0xd18
28#define L2X0_AUXCTRL_OFFSET 0xd1c
29#define L2X0_PREFETCH_CTRL_OFFSET 0xd20
30
31/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
32#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04
33#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08
34
35#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)
36#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)
37#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508)
38
39/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */
40#define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
41#define WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x694)
42#define WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6a4)
43#define WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6b4)
44#define AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x6c4)
45#define AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x6c8)
46#define PTMSYNCREQ_MASK_OFFSET (SAR_BANK3_OFFSET + 0x6cc)
47#define PTMSYNCREQ_EN_OFFSET (SAR_BANK3_OFFSET + 0x6d0)
48#define SAR_BACKUP_STATUS_WAKEUPGEN 0x10
49
50#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 373d1f15c4eb..5192cabb40ed 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -136,6 +136,7 @@
136#include <linux/list.h> 136#include <linux/list.h>
137#include <linux/mutex.h> 137#include <linux/mutex.h>
138#include <linux/spinlock.h> 138#include <linux/spinlock.h>
139#include <linux/slab.h>
139 140
140#include "common.h" 141#include "common.h"
141#include <plat/cpu.h> 142#include <plat/cpu.h>
@@ -381,6 +382,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
381} 382}
382 383
383/** 384/**
385 * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux
386 * @oh: struct omap_hwmod *
387 * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
388 *
389 * Set or clear the I/O pad wakeup flag in the mux entries for the
390 * hwmod @oh. This function changes the @oh->mux->pads_dynamic array
391 * in memory. If the hwmod is currently idled, and the new idle
392 * values don't match the previous ones, this function will also
393 * update the SCM PADCTRL registers. Otherwise, if the hwmod is not
394 * currently idled, this function won't touch the hardware: the new
395 * mux settings are written to the SCM PADCTRL registers when the
396 * hwmod is idled. No return value.
397 */
398static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
399{
400 struct omap_device_pad *pad;
401 bool change = false;
402 u16 prev_idle;
403 int j;
404
405 if (!oh->mux || !oh->mux->enabled)
406 return;
407
408 for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
409 pad = oh->mux->pads_dynamic[j];
410
411 if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
412 continue;
413
414 prev_idle = pad->idle;
415
416 if (set_wake)
417 pad->idle |= OMAP_WAKEUP_EN;
418 else
419 pad->idle &= ~OMAP_WAKEUP_EN;
420
421 if (prev_idle != pad->idle)
422 change = true;
423 }
424
425 if (change && oh->_state == _HWMOD_STATE_IDLE)
426 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
427}
428
429/**
384 * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware 430 * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
385 * @oh: struct omap_hwmod * 431 * @oh: struct omap_hwmod *
386 * 432 *
@@ -1449,6 +1495,25 @@ static int _enable(struct omap_hwmod *oh)
1449 1495
1450 pr_debug("omap_hwmod: %s: enabling\n", oh->name); 1496 pr_debug("omap_hwmod: %s: enabling\n", oh->name);
1451 1497
1498 /*
1499 * hwmods with HWMOD_INIT_NO_IDLE flag set are left
1500 * in enabled state at init.
1501 * Now that someone is really trying to enable them,
1502 * just ensure that the hwmod mux is set.
1503 */
1504 if (oh->_int_flags & _HWMOD_SKIP_ENABLE) {
1505 /*
1506 * If the caller has mux data populated, do the mux'ing
1507 * which wouldn't have been done as part of the _enable()
1508 * done during setup.
1509 */
1510 if (oh->mux)
1511 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
1512
1513 oh->_int_flags &= ~_HWMOD_SKIP_ENABLE;
1514 return 0;
1515 }
1516
1452 if (oh->_state != _HWMOD_STATE_INITIALIZED && 1517 if (oh->_state != _HWMOD_STATE_INITIALIZED &&
1453 oh->_state != _HWMOD_STATE_IDLE && 1518 oh->_state != _HWMOD_STATE_IDLE &&
1454 oh->_state != _HWMOD_STATE_DISABLED) { 1519 oh->_state != _HWMOD_STATE_DISABLED) {
@@ -1744,8 +1809,10 @@ static int _setup(struct omap_hwmod *oh, void *data)
1744 * it should be set by the core code as a runtime flag during startup 1809 * it should be set by the core code as a runtime flag during startup
1745 */ 1810 */
1746 if ((oh->flags & HWMOD_INIT_NO_IDLE) && 1811 if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
1747 (postsetup_state == _HWMOD_STATE_IDLE)) 1812 (postsetup_state == _HWMOD_STATE_IDLE)) {
1813 oh->_int_flags |= _HWMOD_SKIP_ENABLE;
1748 postsetup_state = _HWMOD_STATE_ENABLED; 1814 postsetup_state = _HWMOD_STATE_ENABLED;
1815 }
1749 1816
1750 if (postsetup_state == _HWMOD_STATE_IDLE) 1817 if (postsetup_state == _HWMOD_STATE_IDLE)
1751 _idle(oh); 1818 _idle(oh);
@@ -2416,6 +2483,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
2416 v = oh->_sysc_cache; 2483 v = oh->_sysc_cache;
2417 _enable_wakeup(oh, &v); 2484 _enable_wakeup(oh, &v);
2418 _write_sysconfig(v, oh); 2485 _write_sysconfig(v, oh);
2486 _set_idle_ioring_wakeup(oh, true);
2419 spin_unlock_irqrestore(&oh->_lock, flags); 2487 spin_unlock_irqrestore(&oh->_lock, flags);
2420 2488
2421 return 0; 2489 return 0;
@@ -2446,6 +2514,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
2446 v = oh->_sysc_cache; 2514 v = oh->_sysc_cache;
2447 _disable_wakeup(oh, &v); 2515 _disable_wakeup(oh, &v);
2448 _write_sysconfig(v, oh); 2516 _write_sysconfig(v, oh);
2517 _set_idle_ioring_wakeup(oh, false);
2449 spin_unlock_irqrestore(&oh->_lock, flags); 2518 spin_unlock_irqrestore(&oh->_lock, flags);
2450 2519
2451 return 0; 2520 return 0;
@@ -2662,3 +2731,57 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
2662 2731
2663 return 0; 2732 return 0;
2664} 2733}
2734
2735/**
2736 * omap_hwmod_pad_route_irq - route an I/O pad wakeup to a particular MPU IRQ
2737 * @oh: struct omap_hwmod * containing hwmod mux entries
2738 * @pad_idx: array index in oh->mux of the hwmod mux entry to route wakeup
2739 * @irq_idx: the hwmod mpu_irqs array index of the IRQ to trigger on wakeup
2740 *
2741 * When an I/O pad wakeup arrives for the dynamic or wakeup hwmod mux
2742 * entry number @pad_idx for the hwmod @oh, trigger the interrupt
2743 * service routine for the hwmod's mpu_irqs array index @irq_idx. If
2744 * this function is not called for a given pad_idx, then the ISR
2745 * associated with @oh's first MPU IRQ will be triggered when an I/O
2746 * pad wakeup occurs on that pad. Note that @pad_idx is the index of
2747 * the _dynamic or wakeup_ entry: if there are other entries not
2748 * marked with OMAP_DEVICE_PAD_WAKEUP or OMAP_DEVICE_PAD_REMUX, these
2749 * entries are NOT COUNTED in the dynamic pad index. This function
2750 * must be called separately for each pad that requires its interrupt
2751 * to be re-routed this way. Returns -EINVAL if there is an argument
2752 * problem or if @oh does not have hwmod mux entries or MPU IRQs;
2753 * returns -ENOMEM if memory cannot be allocated; or 0 upon success.
2754 *
2755 * XXX This function interface is fragile. Rather than using array
2756 * indexes, which are subject to unpredictable change, it should be
2757 * using hwmod IRQ names, and some other stable key for the hwmod mux
2758 * pad records.
2759 */
2760int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
2761{
2762 int nr_irqs;
2763
2764 might_sleep();
2765
2766 if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 ||
2767 pad_idx >= oh->mux->nr_pads_dynamic)
2768 return -EINVAL;
2769
2770 /* Check the number of available mpu_irqs */
2771 for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++)
2772 ;
2773
2774 if (irq_idx >= nr_irqs)
2775 return -EINVAL;
2776
2777 if (!oh->mux->irqs) {
2778 /* XXX What frees this? */
2779 oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic,
2780 GFP_KERNEL);
2781 if (!oh->mux->irqs)
2782 return -ENOMEM;
2783 }
2784 oh->mux->irqs[pad_idx] = irq_idx;
2785
2786 return 0;
2787}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 4e166add2f35..b737b11e4499 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -21,6 +21,7 @@ extern void omap_sram_idle(void);
21extern int omap3_can_sleep(void); 21extern int omap3_can_sleep(void);
22extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); 22extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
23extern int omap3_idle_init(void); 23extern int omap3_idle_init(void);
24extern int omap4_idle_init(void);
24 25
25#if defined(CONFIG_PM_OPP) 26#if defined(CONFIG_PM_OPP)
26extern int omap3_opp_init(void); 27extern int omap3_opp_init(void);
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index ef8595c80296..b8822f8b2891 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -30,7 +30,6 @@
30#include <linux/irq.h> 30#include <linux/irq.h>
31#include <linux/time.h> 31#include <linux/time.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/console.h>
34 33
35#include <asm/mach/time.h> 34#include <asm/mach/time.h>
36#include <asm/mach/irq.h> 35#include <asm/mach/irq.h>
@@ -127,27 +126,11 @@ static void omap2_enter_full_retention(void)
127 if (omap_irq_pending()) 126 if (omap_irq_pending())
128 goto no_sleep; 127 goto no_sleep;
129 128
130 /* Block console output in case it is on one of the OMAP UARTs */
131 if (!is_suspending())
132 if (!console_trylock())
133 goto no_sleep;
134
135 omap_uart_prepare_idle(0);
136 omap_uart_prepare_idle(1);
137 omap_uart_prepare_idle(2);
138
139 /* Jump to SRAM suspend code */ 129 /* Jump to SRAM suspend code */
140 omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), 130 omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
141 OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), 131 OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
142 OMAP_SDRC_REGADDR(SDRC_POWER)); 132 OMAP_SDRC_REGADDR(SDRC_POWER));
143 133
144 omap_uart_resume_idle(2);
145 omap_uart_resume_idle(1);
146 omap_uart_resume_idle(0);
147
148 if (!is_suspending())
149 console_unlock();
150
151no_sleep: 134no_sleep:
152 omap2_gpio_resume_after_idle(); 135 omap2_gpio_resume_after_idle();
153 136
@@ -239,8 +222,6 @@ static int omap2_can_sleep(void)
239{ 222{
240 if (omap2_fclks_active()) 223 if (omap2_fclks_active())
241 return 0; 224 return 0;
242 if (!omap_uart_can_sleep())
243 return 0;
244 if (osc_ck->usecount > 1) 225 if (osc_ck->usecount > 1)
245 return 0; 226 return 0;
246 if (omap_dma_running()) 227 if (omap_dma_running())
@@ -291,7 +272,6 @@ static int omap2_pm_suspend(void)
291 mir1 = omap_readl(0x480fe0a4); 272 mir1 = omap_readl(0x480fe0a4);
292 omap_writel(1 << 5, 0x480fe0ac); 273 omap_writel(1 << 5, 0x480fe0ac);
293 274
294 omap_uart_prepare_suspend();
295 omap2_enter_full_retention(); 275 omap2_enter_full_retention();
296 276
297 omap_writel(mir1, 0x480fe0a4); 277 omap_writel(mir1, 0x480fe0a4);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fa637dfdda53..fc6987578920 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -28,7 +28,6 @@
28#include <linux/clk.h> 28#include <linux/clk.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/console.h>
32#include <trace/events/power.h> 31#include <trace/events/power.h>
33 32
34#include <asm/suspend.h> 33#include <asm/suspend.h>
@@ -36,7 +35,6 @@
36#include <plat/sram.h> 35#include <plat/sram.h>
37#include "clockdomain.h" 36#include "clockdomain.h"
38#include "powerdomain.h" 37#include "powerdomain.h"
39#include <plat/serial.h>
40#include <plat/sdrc.h> 38#include <plat/sdrc.h>
41#include <plat/prcm.h> 39#include <plat/prcm.h>
42#include <plat/gpmc.h> 40#include <plat/gpmc.h>
@@ -54,15 +52,6 @@
54 52
55#ifdef CONFIG_SUSPEND 53#ifdef CONFIG_SUSPEND
56static suspend_state_t suspend_state = PM_SUSPEND_ON; 54static suspend_state_t suspend_state = PM_SUSPEND_ON;
57static inline bool is_suspending(void)
58{
59 return (suspend_state != PM_SUSPEND_ON) && console_suspend_enabled;
60}
61#else
62static inline bool is_suspending(void)
63{
64 return false;
65}
66#endif 55#endif
67 56
68/* pm34xx errata defined in pm.h */ 57/* pm34xx errata defined in pm.h */
@@ -195,7 +184,7 @@ static void omap3_save_secure_ram_context(void)
195 * that any peripheral wake-up events occurring while attempting to 184 * that any peripheral wake-up events occurring while attempting to
196 * clear the PM_WKST_x are detected and cleared. 185 * clear the PM_WKST_x are detected and cleared.
197 */ 186 */
198static int prcm_clear_mod_irqs(s16 module, u8 regs) 187static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
199{ 188{
200 u32 wkst, fclk, iclk, clken; 189 u32 wkst, fclk, iclk, clken;
201 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; 190 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
@@ -207,6 +196,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
207 196
208 wkst = omap2_prm_read_mod_reg(module, wkst_off); 197 wkst = omap2_prm_read_mod_reg(module, wkst_off);
209 wkst &= omap2_prm_read_mod_reg(module, grpsel_off); 198 wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
199 wkst &= ~ignore_bits;
210 if (wkst) { 200 if (wkst) {
211 iclk = omap2_cm_read_mod_reg(module, iclk_off); 201 iclk = omap2_cm_read_mod_reg(module, iclk_off);
212 fclk = omap2_cm_read_mod_reg(module, fclk_off); 202 fclk = omap2_cm_read_mod_reg(module, fclk_off);
@@ -222,6 +212,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
222 omap2_cm_set_mod_reg_bits(clken, module, fclk_off); 212 omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
223 omap2_prm_write_mod_reg(wkst, module, wkst_off); 213 omap2_prm_write_mod_reg(wkst, module, wkst_off);
224 wkst = omap2_prm_read_mod_reg(module, wkst_off); 214 wkst = omap2_prm_read_mod_reg(module, wkst_off);
215 wkst &= ~ignore_bits;
225 c++; 216 c++;
226 } 217 }
227 omap2_cm_write_mod_reg(iclk, module, iclk_off); 218 omap2_cm_write_mod_reg(iclk, module, iclk_off);
@@ -231,76 +222,35 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
231 return c; 222 return c;
232} 223}
233 224
234static int _prcm_int_handle_wakeup(void) 225static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
235{ 226{
236 int c; 227 int c;
237 228
238 c = prcm_clear_mod_irqs(WKUP_MOD, 1); 229 c = prcm_clear_mod_irqs(WKUP_MOD, 1,
239 c += prcm_clear_mod_irqs(CORE_MOD, 1); 230 ~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK));
240 c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
241 if (omap_rev() > OMAP3430_REV_ES1_0) {
242 c += prcm_clear_mod_irqs(CORE_MOD, 3);
243 c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
244 }
245 231
246 return c; 232 return c ? IRQ_HANDLED : IRQ_NONE;
247} 233}
248 234
249/* 235static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
250 * PRCM Interrupt Handler
251 *
252 * The PRM_IRQSTATUS_MPU register indicates if there are any pending
253 * interrupts from the PRCM for the MPU. These bits must be cleared in
254 * order to clear the PRCM interrupt. The PRCM interrupt handler is
255 * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
256 * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
257 * register indicates that a wake-up event is pending for the MPU and
258 * this bit can only be cleared if the all the wake-up events latched
259 * in the various PM_WKST_x registers have been cleared. The interrupt
260 * handler is implemented using a do-while loop so that if a wake-up
261 * event occurred during the processing of the prcm interrupt handler
262 * (setting a bit in the corresponding PM_WKST_x register and thus
263 * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
264 * this would be handled.
265 */
266static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
267{ 236{
268 u32 irqenable_mpu, irqstatus_mpu; 237 int c;
269 int c = 0;
270
271 irqenable_mpu = omap2_prm_read_mod_reg(OCP_MOD,
272 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
273 irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
274 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
275 irqstatus_mpu &= irqenable_mpu;
276
277 do {
278 if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
279 OMAP3430_IO_ST_MASK)) {
280 c = _prcm_int_handle_wakeup();
281
282 /*
283 * Is the MPU PRCM interrupt handler racing with the
284 * IVA2 PRCM interrupt handler ?
285 */
286 WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
287 "but no wakeup sources are marked\n");
288 } else {
289 /* XXX we need to expand our PRCM interrupt handler */
290 WARN(1, "prcm: WARNING: PRCM interrupt received, but "
291 "no code to handle it (%08x)\n", irqstatus_mpu);
292 }
293
294 omap2_prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
295 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
296
297 irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
298 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
299 irqstatus_mpu &= irqenable_mpu;
300 238
301 } while (irqstatus_mpu); 239 /*
240 * Clear all except ST_IO and ST_IO_CHAIN for wkup module,
241 * these are handled in a separate handler to avoid acking
242 * IO events before parsing in mux code
243 */
244 c = prcm_clear_mod_irqs(WKUP_MOD, 1,
245 OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK);
246 c += prcm_clear_mod_irqs(CORE_MOD, 1, 0);
247 c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
248 if (omap_rev() > OMAP3430_REV_ES1_0) {
249 c += prcm_clear_mod_irqs(CORE_MOD, 3, 0);
250 c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
251 }
302 252
303 return IRQ_HANDLED; 253 return c ? IRQ_HANDLED : IRQ_NONE;
304} 254}
305 255
306static void omap34xx_save_context(u32 *save) 256static void omap34xx_save_context(u32 *save)
@@ -376,20 +326,11 @@ void omap_sram_idle(void)
376 omap3_enable_io_chain(); 326 omap3_enable_io_chain();
377 } 327 }
378 328
379 /* Block console output in case it is on one of the OMAP UARTs */
380 if (!is_suspending())
381 if (per_next_state < PWRDM_POWER_ON ||
382 core_next_state < PWRDM_POWER_ON)
383 if (!console_trylock())
384 goto console_still_active;
385
386 pwrdm_pre_transition(); 329 pwrdm_pre_transition();
387 330
388 /* PER */ 331 /* PER */
389 if (per_next_state < PWRDM_POWER_ON) { 332 if (per_next_state < PWRDM_POWER_ON) {
390 per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; 333 per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
391 omap_uart_prepare_idle(2);
392 omap_uart_prepare_idle(3);
393 omap2_gpio_prepare_for_idle(per_going_off); 334 omap2_gpio_prepare_for_idle(per_going_off);
394 if (per_next_state == PWRDM_POWER_OFF) 335 if (per_next_state == PWRDM_POWER_OFF)
395 omap3_per_save_context(); 336 omap3_per_save_context();
@@ -397,8 +338,6 @@ void omap_sram_idle(void)
397 338
398 /* CORE */ 339 /* CORE */
399 if (core_next_state < PWRDM_POWER_ON) { 340 if (core_next_state < PWRDM_POWER_ON) {
400 omap_uart_prepare_idle(0);
401 omap_uart_prepare_idle(1);
402 if (core_next_state == PWRDM_POWER_OFF) { 341 if (core_next_state == PWRDM_POWER_OFF) {
403 omap3_core_save_context(); 342 omap3_core_save_context();
404 omap3_cm_save_context(); 343 omap3_cm_save_context();
@@ -447,8 +386,6 @@ void omap_sram_idle(void)
447 omap3_sram_restore_context(); 386 omap3_sram_restore_context();
448 omap2_sms_restore_context(); 387 omap2_sms_restore_context();
449 } 388 }
450 omap_uart_resume_idle(0);
451 omap_uart_resume_idle(1);
452 if (core_next_state == PWRDM_POWER_OFF) 389 if (core_next_state == PWRDM_POWER_OFF)
453 omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, 390 omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
454 OMAP3430_GR_MOD, 391 OMAP3430_GR_MOD,
@@ -464,14 +401,8 @@ void omap_sram_idle(void)
464 omap2_gpio_resume_after_idle(); 401 omap2_gpio_resume_after_idle();
465 if (per_prev_state == PWRDM_POWER_OFF) 402 if (per_prev_state == PWRDM_POWER_OFF)
466 omap3_per_restore_context(); 403 omap3_per_restore_context();
467 omap_uart_resume_idle(2);
468 omap_uart_resume_idle(3);
469 } 404 }
470 405
471 if (!is_suspending())
472 console_unlock();
473
474console_still_active:
475 /* Disable IO-PAD and IO-CHAIN wakeup */ 406 /* Disable IO-PAD and IO-CHAIN wakeup */
476 if (omap3_has_io_wakeup() && 407 if (omap3_has_io_wakeup() &&
477 (per_next_state < PWRDM_POWER_ON || 408 (per_next_state < PWRDM_POWER_ON ||
@@ -485,21 +416,11 @@ console_still_active:
485 clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); 416 clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
486} 417}
487 418
488int omap3_can_sleep(void)
489{
490 if (!omap_uart_can_sleep())
491 return 0;
492 return 1;
493}
494
495static void omap3_pm_idle(void) 419static void omap3_pm_idle(void)
496{ 420{
497 local_irq_disable(); 421 local_irq_disable();
498 local_fiq_disable(); 422 local_fiq_disable();
499 423
500 if (!omap3_can_sleep())
501 goto out;
502
503 if (omap_irq_pending() || need_resched()) 424 if (omap_irq_pending() || need_resched())
504 goto out; 425 goto out;
505 426
@@ -533,7 +454,6 @@ static int omap3_pm_suspend(void)
533 goto restore; 454 goto restore;
534 } 455 }
535 456
536 omap_uart_prepare_suspend();
537 omap3_intc_suspend(); 457 omap3_intc_suspend();
538 458
539 omap_sram_idle(); 459 omap_sram_idle();
@@ -580,22 +500,27 @@ static int omap3_pm_begin(suspend_state_t state)
580{ 500{
581 disable_hlt(); 501 disable_hlt();
582 suspend_state = state; 502 suspend_state = state;
583 omap_uart_enable_irqs(0); 503 omap_prcm_irq_prepare();
584 return 0; 504 return 0;
585} 505}
586 506
587static void omap3_pm_end(void) 507static void omap3_pm_end(void)
588{ 508{
589 suspend_state = PM_SUSPEND_ON; 509 suspend_state = PM_SUSPEND_ON;
590 omap_uart_enable_irqs(1);
591 enable_hlt(); 510 enable_hlt();
592 return; 511 return;
593} 512}
594 513
514static void omap3_pm_finish(void)
515{
516 omap_prcm_irq_complete();
517}
518
595static const struct platform_suspend_ops omap_pm_ops = { 519static const struct platform_suspend_ops omap_pm_ops = {
596 .begin = omap3_pm_begin, 520 .begin = omap3_pm_begin,
597 .end = omap3_pm_end, 521 .end = omap3_pm_end,
598 .enter = omap3_pm_enter, 522 .enter = omap3_pm_enter,
523 .finish = omap3_pm_finish,
599 .valid = suspend_valid_only_mem, 524 .valid = suspend_valid_only_mem,
600}; 525};
601#endif /* CONFIG_SUSPEND */ 526#endif /* CONFIG_SUSPEND */
@@ -701,10 +626,6 @@ static void __init prcm_setup_regs(void)
701 OMAP3430_GRPSEL_GPT1_MASK | 626 OMAP3430_GRPSEL_GPT1_MASK |
702 OMAP3430_GRPSEL_GPT12_MASK, 627 OMAP3430_GRPSEL_GPT12_MASK,
703 WKUP_MOD, OMAP3430_PM_MPUGRPSEL); 628 WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
704 /* For some reason IO doesn't generate wakeup event even if
705 * it is selected to mpu wakeup goup */
706 omap2_prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK,
707 OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
708 629
709 /* Enable PM_WKEN to support DSS LPR */ 630 /* Enable PM_WKEN to support DSS LPR */
710 omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK, 631 omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
@@ -881,12 +802,21 @@ static int __init omap3_pm_init(void)
881 * supervised mode for powerdomains */ 802 * supervised mode for powerdomains */
882 prcm_setup_regs(); 803 prcm_setup_regs();
883 804
884 ret = request_irq(INT_34XX_PRCM_MPU_IRQ, 805 ret = request_irq(omap_prcm_event_to_irq("wkup"),
885 (irq_handler_t)prcm_interrupt_handler, 806 _prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL);
886 IRQF_DISABLED, "prcm", NULL); 807
808 if (ret) {
809 pr_err("pm: Failed to request pm_wkup irq\n");
810 goto err1;
811 }
812
813 /* IO interrupt is shared with mux code */
814 ret = request_irq(omap_prcm_event_to_irq("io"),
815 _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io",
816 omap3_pm_init);
817
887 if (ret) { 818 if (ret) {
888 printk(KERN_ERR "request_irq failed to register for 0x%x\n", 819 pr_err("pm: Failed to request pm_io irq\n");
889 INT_34XX_PRCM_MPU_IRQ);
890 goto err1; 820 goto err1;
891 } 821 }
892 822
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 8edb015f5618..c264ef7219c1 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * OMAP4 Power Management Routines 2 * OMAP4 Power Management Routines
3 * 3 *
4 * Copyright (C) 2010 Texas Instruments, Inc. 4 * Copyright (C) 2010-2011 Texas Instruments, Inc.
5 * Rajendra Nayak <rnayak@ti.com> 5 * Rajendra Nayak <rnayak@ti.com>
6 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * 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 * it under the terms of the GNU General Public License version 2 as
@@ -17,13 +18,16 @@
17#include <linux/slab.h> 18#include <linux/slab.h>
18 19
19#include "common.h" 20#include "common.h"
21#include "clockdomain.h"
20#include "powerdomain.h" 22#include "powerdomain.h"
23#include "pm.h"
21 24
22struct power_state { 25struct power_state {
23 struct powerdomain *pwrdm; 26 struct powerdomain *pwrdm;
24 u32 next_state; 27 u32 next_state;
25#ifdef CONFIG_SUSPEND 28#ifdef CONFIG_SUSPEND
26 u32 saved_state; 29 u32 saved_state;
30 u32 saved_logic_state;
27#endif 31#endif
28 struct list_head node; 32 struct list_head node;
29}; 33};
@@ -33,7 +37,50 @@ static LIST_HEAD(pwrst_list);
33#ifdef CONFIG_SUSPEND 37#ifdef CONFIG_SUSPEND
34static int omap4_pm_suspend(void) 38static int omap4_pm_suspend(void)
35{ 39{
36 do_wfi(); 40 struct power_state *pwrst;
41 int state, ret = 0;
42 u32 cpu_id = smp_processor_id();
43
44 /* Save current powerdomain state */
45 list_for_each_entry(pwrst, &pwrst_list, node) {
46 pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
47 pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm);
48 }
49
50 /* Set targeted power domain states by suspend */
51 list_for_each_entry(pwrst, &pwrst_list, node) {
52 omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
53 pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF);
54 }
55
56 /*
57 * For MPUSS to hit power domain retention(CSWR or OSWR),
58 * CPU0 and CPU1 power domains need to be in OFF or DORMANT state,
59 * since CPU power domain CSWR is not supported by hardware
60 * Only master CPU follows suspend path. All other CPUs follow
61 * CPU hotplug path in system wide suspend. On OMAP4, CPU power
62 * domain CSWR is not supported by hardware.
63 * More details can be found in OMAP4430 TRM section 4.3.4.2.
64 */
65 omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF);
66
67 /* Restore next powerdomain state */
68 list_for_each_entry(pwrst, &pwrst_list, node) {
69 state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
70 if (state > pwrst->next_state) {
71 pr_info("Powerdomain (%s) didn't enter "
72 "target state %d\n",
73 pwrst->pwrdm->name, pwrst->next_state);
74 ret = -1;
75 }
76 omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
77 pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
78 }
79 if (ret)
80 pr_crit("Could not enter target state in pm_suspend\n");
81 else
82 pr_info("Successfully put all powerdomains to target state\n");
83
37 return 0; 84 return 0;
38} 85}
39 86
@@ -73,6 +120,22 @@ static const struct platform_suspend_ops omap_pm_ops = {
73}; 120};
74#endif /* CONFIG_SUSPEND */ 121#endif /* CONFIG_SUSPEND */
75 122
123/*
124 * Enable hardware supervised mode for all clockdomains if it's
125 * supported. Initiate sleep transition for other clockdomains, if
126 * they are not used
127 */
128static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
129{
130 if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
131 clkdm_allow_idle(clkdm);
132 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
133 atomic_read(&clkdm->usecount) == 0)
134 clkdm_sleep(clkdm);
135 return 0;
136}
137
138
76static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) 139static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
77{ 140{
78 struct power_state *pwrst; 141 struct power_state *pwrst;
@@ -80,14 +143,48 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
80 if (!pwrdm->pwrsts) 143 if (!pwrdm->pwrsts)
81 return 0; 144 return 0;
82 145
146 /*
147 * Skip CPU0 and CPU1 power domains. CPU1 is programmed
148 * through hotplug path and CPU0 explicitly programmed
149 * further down in the code path
150 */
151 if (!strncmp(pwrdm->name, "cpu", 3))
152 return 0;
153
154 /*
155 * FIXME: Remove this check when core retention is supported
156 * Only MPUSS power domain is added in the list.
157 */
158 if (strcmp(pwrdm->name, "mpu_pwrdm"))
159 return 0;
160
83 pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); 161 pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
84 if (!pwrst) 162 if (!pwrst)
85 return -ENOMEM; 163 return -ENOMEM;
164
86 pwrst->pwrdm = pwrdm; 165 pwrst->pwrdm = pwrdm;
87 pwrst->next_state = PWRDM_POWER_ON; 166 pwrst->next_state = PWRDM_POWER_RET;
88 list_add(&pwrst->node, &pwrst_list); 167 list_add(&pwrst->node, &pwrst_list);
89 168
90 return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state); 169 return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
170}
171
172/**
173 * omap_default_idle - OMAP4 default ilde routine.'
174 *
175 * Implements OMAP4 memory, IO ordering requirements which can't be addressed
176 * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and
177 * by secondary CPU with CONFIG_CPUIDLE.
178 */
179static void omap_default_idle(void)
180{
181 local_irq_disable();
182 local_fiq_disable();
183
184 omap_do_wfi();
185
186 local_fiq_enable();
187 local_irq_enable();
91} 188}
92 189
93/** 190/**
@@ -99,10 +196,17 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
99static int __init omap4_pm_init(void) 196static int __init omap4_pm_init(void)
100{ 197{
101 int ret; 198 int ret;
199 struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
200 struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
102 201
103 if (!cpu_is_omap44xx()) 202 if (!cpu_is_omap44xx())
104 return -ENODEV; 203 return -ENODEV;
105 204
205 if (omap_rev() == OMAP4430_REV_ES1_0) {
206 WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
207 return -ENODEV;
208 }
209
106 pr_err("Power Management for TI OMAP4.\n"); 210 pr_err("Power Management for TI OMAP4.\n");
107 211
108 ret = pwrdm_for_each(pwrdms_setup, NULL); 212 ret = pwrdm_for_each(pwrdms_setup, NULL);
@@ -111,10 +215,51 @@ static int __init omap4_pm_init(void)
111 goto err2; 215 goto err2;
112 } 216 }
113 217
218 /*
219 * The dynamic dependency between MPUSS -> MEMIF and
220 * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
221 * expected. The hardware recommendation is to enable static
222 * dependencies for these to avoid system lock ups or random crashes.
223 */
224 mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
225 emif_clkdm = clkdm_lookup("l3_emif_clkdm");
226 l3_1_clkdm = clkdm_lookup("l3_1_clkdm");
227 l3_2_clkdm = clkdm_lookup("l3_2_clkdm");
228 l4_per_clkdm = clkdm_lookup("l4_per_clkdm");
229 ducati_clkdm = clkdm_lookup("ducati_clkdm");
230 if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
231 (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
232 goto err2;
233
234 ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
235 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
236 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm);
237 ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per_clkdm);
238 ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);
239 ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
240 if (ret) {
241 pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 "
242 "wakeup dependency\n");
243 goto err2;
244 }
245
246 ret = omap4_mpuss_init();
247 if (ret) {
248 pr_err("Failed to initialise OMAP4 MPUSS\n");
249 goto err2;
250 }
251
252 (void) clkdm_for_each(clkdms_setup, NULL);
253
114#ifdef CONFIG_SUSPEND 254#ifdef CONFIG_SUSPEND
115 suspend_set_ops(&omap_pm_ops); 255 suspend_set_ops(&omap_pm_ops);
116#endif /* CONFIG_SUSPEND */ 256#endif /* CONFIG_SUSPEND */
117 257
258 /* Overwrite the default arch_idle() */
259 pm_idle = omap_default_idle;
260
261 omap4_idle_init();
262
118err2: 263err2:
119 return ret; 264 return ret;
120} 265}
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index da2d80f5fcbd..5aa5435e3ff1 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -4,7 +4,7 @@
4/* 4/*
5 * OMAP2/3 PRCM base and module definitions 5 * OMAP2/3 PRCM base and module definitions
6 * 6 *
7 * Copyright (C) 2007-2009 Texas Instruments, Inc. 7 * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc.
8 * Copyright (C) 2007-2009 Nokia Corporation 8 * Copyright (C) 2007-2009 Nokia Corporation
9 * 9 *
10 * Written by Paul Walmsley 10 * Written by Paul Walmsley
@@ -410,6 +410,79 @@
410extern void __iomem *prm_base; 410extern void __iomem *prm_base;
411extern void __iomem *cm_base; 411extern void __iomem *cm_base;
412extern void __iomem *cm2_base; 412extern void __iomem *cm2_base;
413
414/**
415 * struct omap_prcm_irq - describes a PRCM interrupt bit
416 * @name: a short name describing the interrupt type, e.g. "wkup" or "io"
417 * @offset: the bit shift of the interrupt inside the IRQ{ENABLE,STATUS} regs
418 * @priority: should this interrupt be handled before @priority=false IRQs?
419 *
420 * Describes interrupt bits inside the PRM_IRQ{ENABLE,STATUS}_MPU* registers.
421 * On systems with multiple PRM MPU IRQ registers, the bitfields read from
422 * the registers are concatenated, so @offset could be > 31 on these systems -
423 * see omap_prm_irq_handler() for more details. I/O ring interrupts should
424 * have @priority set to true.
425 */
426struct omap_prcm_irq {
427 const char *name;
428 unsigned int offset;
429 bool priority;
430};
431
432/**
433 * struct omap_prcm_irq_setup - PRCM interrupt controller details
434 * @ack: PRM register offset for the first PRM_IRQSTATUS_MPU register
435 * @mask: PRM register offset for the first PRM_IRQENABLE_MPU register
436 * @nr_regs: number of PRM_IRQ{STATUS,ENABLE}_MPU* registers
437 * @nr_irqs: number of entries in the @irqs array
438 * @irqs: ptr to an array of PRCM interrupt bits (see @nr_irqs)
439 * @irq: MPU IRQ asserted when a PRCM interrupt arrives
440 * @read_pending_irqs: fn ptr to determine if any PRCM IRQs are pending
441 * @ocp_barrier: fn ptr to force buffered PRM writes to complete
442 * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs
443 * @restore_irqen: fn ptr to save and clear IRQENABLE regs
444 * @saved_mask: IRQENABLE regs are saved here during suspend
445 * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true
446 * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init
447 * @suspended: set to true after Linux suspend code has called our ->prepare()
448 * @suspend_save_flag: set to true after IRQ masks have been saved and disabled
449 *
450 * @saved_mask, @priority_mask, @base_irq, @suspended, and
451 * @suspend_save_flag are populated dynamically, and are not to be
452 * specified in static initializers.
453 */
454struct omap_prcm_irq_setup {
455 u16 ack;
456 u16 mask;
457 u8 nr_regs;
458 u8 nr_irqs;
459 const struct omap_prcm_irq *irqs;
460 int irq;
461 void (*read_pending_irqs)(unsigned long *events);
462 void (*ocp_barrier)(void);
463 void (*save_and_clear_irqen)(u32 *saved_mask);
464 void (*restore_irqen)(u32 *saved_mask);
465 u32 *saved_mask;
466 u32 *priority_mask;
467 int base_irq;
468 bool suspended;
469 bool suspend_save_flag;
470};
471
472/* OMAP_PRCM_IRQ: convenience macro for creating struct omap_prcm_irq records */
473#define OMAP_PRCM_IRQ(_name, _offset, _priority) { \
474 .name = _name, \
475 .offset = _offset, \
476 .priority = _priority \
477 }
478
479extern void omap_prcm_irq_cleanup(void);
480extern int omap_prcm_register_chain_handler(
481 struct omap_prcm_irq_setup *irq_setup);
482extern int omap_prcm_event_to_irq(const char *event);
483extern void omap_prcm_irq_prepare(void);
484extern void omap_prcm_irq_complete(void);
485
413# endif 486# endif
414 487
415#endif 488#endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 9a08ba397327..c1c4d86a79a8 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP2/3 PRM module functions 2 * OMAP2/3 PRM module functions
3 * 3 *
4 * Copyright (C) 2010 Texas Instruments, Inc. 4 * Copyright (C) 2010-2011 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation 5 * Copyright (C) 2010 Nokia Corporation
6 * Benoît Cousson 6 * Benoît Cousson
7 * Paul Walmsley 7 * Paul Walmsley
@@ -27,6 +27,24 @@
27#include "prm-regbits-24xx.h" 27#include "prm-regbits-24xx.h"
28#include "prm-regbits-34xx.h" 28#include "prm-regbits-34xx.h"
29 29
30static const struct omap_prcm_irq omap3_prcm_irqs[] = {
31 OMAP_PRCM_IRQ("wkup", 0, 0),
32 OMAP_PRCM_IRQ("io", 9, 1),
33};
34
35static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
36 .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
37 .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
38 .nr_regs = 1,
39 .irqs = omap3_prcm_irqs,
40 .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
41 .irq = INT_34XX_PRCM_MPU_IRQ,
42 .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
43 .ocp_barrier = &omap3xxx_prm_ocp_barrier,
44 .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
45 .restore_irqen = &omap3xxx_prm_restore_irqen,
46};
47
30u32 omap2_prm_read_mod_reg(s16 module, u16 idx) 48u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
31{ 49{
32 return __raw_readl(prm_base + module + idx); 50 return __raw_readl(prm_base + module + idx);
@@ -212,3 +230,80 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
212{ 230{
213 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset); 231 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
214} 232}
233
234/**
235 * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
236 * @events: ptr to a u32, preallocated by caller
237 *
238 * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
239 * MPU IRQs, and store the result into the u32 pointed to by @events.
240 * No return value.
241 */
242void omap3xxx_prm_read_pending_irqs(unsigned long *events)
243{
244 u32 mask, st;
245
246 /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
247 mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
248 st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
249
250 events[0] = mask & st;
251}
252
253/**
254 * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
255 *
256 * Force any buffered writes to the PRM IP block to complete. Needed
257 * by the PRM IRQ handler, which reads and writes directly to the IP
258 * block, to avoid race conditions after acknowledging or clearing IRQ
259 * bits. No return value.
260 */
261void omap3xxx_prm_ocp_barrier(void)
262{
263 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
264}
265
266/**
267 * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
268 * @saved_mask: ptr to a u32 array to save IRQENABLE bits
269 *
270 * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
271 * must be allocated by the caller. Intended to be used in the PRM
272 * interrupt handler suspend callback. The OCP barrier is needed to
273 * ensure the write to disable PRM interrupts reaches the PRM before
274 * returning; otherwise, spurious interrupts might occur. No return
275 * value.
276 */
277void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
278{
279 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
280 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
281 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
282
283 /* OCP barrier */
284 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
285}
286
287/**
288 * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
289 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
290 *
291 * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
292 * to be used in the PRM interrupt handler resume callback to restore
293 * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
294 * barrier should be needed here; any pending PRM interrupts will fire
295 * once the writes reach the PRM. No return value.
296 */
297void omap3xxx_prm_restore_irqen(u32 *saved_mask)
298{
299 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
300 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
301}
302
303static int __init omap3xxx_prcm_init(void)
304{
305 if (cpu_is_omap34xx())
306 return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
307 return 0;
308}
309subsys_initcall(omap3xxx_prcm_init);
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index cef533df0861..70ac2a19dc5f 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP2/3 Power/Reset Management (PRM) register definitions 2 * OMAP2/3 Power/Reset Management (PRM) register definitions
3 * 3 *
4 * Copyright (C) 2007-2009 Texas Instruments, Inc. 4 * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc.
5 * Copyright (C) 2008-2010 Nokia Corporation 5 * Copyright (C) 2008-2010 Nokia Corporation
6 * Paul Walmsley 6 * Paul Walmsley
7 * 7 *
@@ -314,6 +314,13 @@ void omap3_prm_vp_clear_txdone(u8 vp_id);
314extern u32 omap3_prm_vcvp_read(u8 offset); 314extern u32 omap3_prm_vcvp_read(u8 offset);
315extern void omap3_prm_vcvp_write(u32 val, u8 offset); 315extern void omap3_prm_vcvp_write(u32 val, u8 offset);
316extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 316extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
317
318/* PRM interrupt-related functions */
319extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
320extern void omap3xxx_prm_ocp_barrier(void);
321extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
322extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
323
317#endif /* CONFIG_ARCH_OMAP4 */ 324#endif /* CONFIG_ARCH_OMAP4 */
318 325
319#endif 326#endif
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index dd885eecf22a..33dd655e6aab 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -27,6 +27,24 @@
27#include "prcm44xx.h" 27#include "prcm44xx.h"
28#include "prminst44xx.h" 28#include "prminst44xx.h"
29 29
30static const struct omap_prcm_irq omap4_prcm_irqs[] = {
31 OMAP_PRCM_IRQ("wkup", 0, 0),
32 OMAP_PRCM_IRQ("io", 9, 1),
33};
34
35static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
36 .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
37 .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET,
38 .nr_regs = 2,
39 .irqs = omap4_prcm_irqs,
40 .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs),
41 .irq = OMAP44XX_IRQ_PRCM,
42 .read_pending_irqs = &omap44xx_prm_read_pending_irqs,
43 .ocp_barrier = &omap44xx_prm_ocp_barrier,
44 .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen,
45 .restore_irqen = &omap44xx_prm_restore_irqen,
46};
47
30/* PRM low-level functions */ 48/* PRM low-level functions */
31 49
32/* Read a register in a CM/PRM instance in the PRM module */ 50/* Read a register in a CM/PRM instance in the PRM module */
@@ -121,3 +139,101 @@ u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
121 OMAP4430_PRM_DEVICE_INST, 139 OMAP4430_PRM_DEVICE_INST,
122 offset); 140 offset);
123} 141}
142
143static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs)
144{
145 u32 mask, st;
146
147 /* XXX read mask from RAM? */
148 mask = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqen_offs);
149 st = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqst_offs);
150
151 return mask & st;
152}
153
154/**
155 * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
156 * @events: ptr to two consecutive u32s, preallocated by caller
157 *
158 * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM
159 * MPU IRQs, and store the result into the two u32s pointed to by @events.
160 * No return value.
161 */
162void omap44xx_prm_read_pending_irqs(unsigned long *events)
163{
164 events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET,
165 OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
166
167 events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET,
168 OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET);
169}
170
171/**
172 * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
173 *
174 * Force any buffered writes to the PRM IP block to complete. Needed
175 * by the PRM IRQ handler, which reads and writes directly to the IP
176 * block, to avoid race conditions after acknowledging or clearing IRQ
177 * bits. No return value.
178 */
179void omap44xx_prm_ocp_barrier(void)
180{
181 omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
182 OMAP4_REVISION_PRM_OFFSET);
183}
184
185/**
186 * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs
187 * @saved_mask: ptr to a u32 array to save IRQENABLE bits
188 *
189 * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to
190 * @saved_mask. @saved_mask must be allocated by the caller.
191 * Intended to be used in the PRM interrupt handler suspend callback.
192 * The OCP barrier is needed to ensure the write to disable PRM
193 * interrupts reaches the PRM before returning; otherwise, spurious
194 * interrupts might occur. No return value.
195 */
196void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
197{
198 saved_mask[0] =
199 omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
200 OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
201 saved_mask[1] =
202 omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
203 OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET);
204
205 omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST,
206 OMAP4_PRM_IRQENABLE_MPU_OFFSET);
207 omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST,
208 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
209
210 /* OCP barrier */
211 omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
212 OMAP4_REVISION_PRM_OFFSET);
213}
214
215/**
216 * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args
217 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
218 *
219 * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from
220 * @saved_mask. Intended to be used in the PRM interrupt handler resume
221 * callback to restore values saved by omap44xx_prm_save_and_clear_irqen().
222 * No OCP barrier should be needed here; any pending PRM interrupts will fire
223 * once the writes reach the PRM. No return value.
224 */
225void omap44xx_prm_restore_irqen(u32 *saved_mask)
226{
227 omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_DEVICE_INST,
228 OMAP4_PRM_IRQENABLE_MPU_OFFSET);
229 omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_DEVICE_INST,
230 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
231}
232
233static int __init omap4xxx_prcm_init(void)
234{
235 if (cpu_is_omap44xx())
236 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
237 return 0;
238}
239subsys_initcall(omap4xxx_prcm_init);
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 3d66ccd849d2..7978092946db 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP44xx PRM instance offset macros 2 * OMAP44xx PRM instance offset macros
3 * 3 *
4 * Copyright (C) 2009-2010 Texas Instruments, Inc. 4 * Copyright (C) 2009-2011 Texas Instruments, Inc.
5 * Copyright (C) 2009-2010 Nokia Corporation 5 * Copyright (C) 2009-2010 Nokia Corporation
6 * 6 *
7 * Paul Walmsley (paul@pwsan.com) 7 * Paul Walmsley (paul@pwsan.com)
@@ -763,6 +763,12 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
763extern void omap4_prm_vcvp_write(u32 val, u8 offset); 763extern void omap4_prm_vcvp_write(u32 val, u8 offset);
764extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 764extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
765 765
766/* PRM interrupt-related functions */
767extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
768extern void omap44xx_prm_ocp_barrier(void);
769extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
770extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
771
766# endif 772# endif
767 773
768#endif 774#endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
new file mode 100644
index 000000000000..860118ab43e2
--- /dev/null
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -0,0 +1,320 @@
1/*
2 * OMAP2+ common Power & Reset Management (PRM) IP block functions
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Tero Kristo <t-kristo@ti.com>
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 * For historical purposes, the API used to configure the PRM
13 * interrupt handler refers to it as the "PRCM interrupt." The
14 * underlying registers are located in the PRM on OMAP3/4.
15 *
16 * XXX This code should eventually be moved to a PRM driver.
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/io.h>
23#include <linux/irq.h>
24#include <linux/interrupt.h>
25#include <linux/slab.h>
26
27#include <mach/system.h>
28#include <plat/common.h>
29#include <plat/prcm.h>
30#include <plat/irqs.h>
31
32#include "prm2xxx_3xxx.h"
33#include "prm44xx.h"
34
35/*
36 * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
37 * XXX this is technically not needed, since
38 * omap_prcm_register_chain_handler() could allocate this based on the
39 * actual amount of memory needed for the SoC
40 */
41#define OMAP_PRCM_MAX_NR_PENDING_REG 2
42
43/*
44 * prcm_irq_chips: an array of all of the "generic IRQ chips" in use
45 * by the PRCM interrupt handler code. There will be one 'chip' per
46 * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair. (So OMAP3 will have
47 * one "chip" and OMAP4 will have two.)
48 */
49static struct irq_chip_generic **prcm_irq_chips;
50
51/*
52 * prcm_irq_setup: the PRCM IRQ parameters for the hardware the code
53 * is currently running on. Defined and passed by initialization code
54 * that calls omap_prcm_register_chain_handler().
55 */
56static struct omap_prcm_irq_setup *prcm_irq_setup;
57
58/* Private functions */
59
60/*
61 * Move priority events from events to priority_events array
62 */
63static void omap_prcm_events_filter_priority(unsigned long *events,
64 unsigned long *priority_events)
65{
66 int i;
67
68 for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
69 priority_events[i] =
70 events[i] & prcm_irq_setup->priority_mask[i];
71 events[i] ^= priority_events[i];
72 }
73}
74
75/*
76 * PRCM Interrupt Handler
77 *
78 * This is a common handler for the OMAP PRCM interrupts. Pending
79 * interrupts are detected by a call to prcm_pending_events and
80 * dispatched accordingly. Clearing of the wakeup events should be
81 * done by the SoC specific individual handlers.
82 */
83static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
84{
85 unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
86 unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
87 struct irq_chip *chip = irq_desc_get_chip(desc);
88 unsigned int virtirq;
89 int nr_irqs = prcm_irq_setup->nr_regs * 32;
90
91 /*
92 * If we are suspended, mask all interrupts from PRCM level,
93 * this does not ack them, and they will be pending until we
94 * re-enable the interrupts, at which point the
95 * omap_prcm_irq_handler will be executed again. The
96 * _save_and_clear_irqen() function must ensure that the PRM
97 * write to disable all IRQs has reached the PRM before
98 * returning, or spurious PRCM interrupts may occur during
99 * suspend.
100 */
101 if (prcm_irq_setup->suspended) {
102 prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask);
103 prcm_irq_setup->suspend_save_flag = true;
104 }
105
106 /*
107 * Loop until all pending irqs are handled, since
108 * generic_handle_irq() can cause new irqs to come
109 */
110 while (!prcm_irq_setup->suspended) {
111 prcm_irq_setup->read_pending_irqs(pending);
112
113 /* No bit set, then all IRQs are handled */
114 if (find_first_bit(pending, nr_irqs) >= nr_irqs)
115 break;
116
117 omap_prcm_events_filter_priority(pending, priority_pending);
118
119 /*
120 * Loop on all currently pending irqs so that new irqs
121 * cannot starve previously pending irqs
122 */
123
124 /* Serve priority events first */
125 for_each_set_bit(virtirq, priority_pending, nr_irqs)
126 generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
127
128 /* Serve normal events next */
129 for_each_set_bit(virtirq, pending, nr_irqs)
130 generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
131 }
132 if (chip->irq_ack)
133 chip->irq_ack(&desc->irq_data);
134 if (chip->irq_eoi)
135 chip->irq_eoi(&desc->irq_data);
136 chip->irq_unmask(&desc->irq_data);
137
138 prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */
139}
140
141/* Public functions */
142
143/**
144 * omap_prcm_event_to_irq - given a PRCM event name, returns the
145 * corresponding IRQ on which the handler should be registered
146 * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq
147 *
148 * Returns the Linux internal IRQ ID corresponding to @name upon success,
149 * or -ENOENT upon failure.
150 */
151int omap_prcm_event_to_irq(const char *name)
152{
153 int i;
154
155 if (!prcm_irq_setup || !name)
156 return -ENOENT;
157
158 for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
159 if (!strcmp(prcm_irq_setup->irqs[i].name, name))
160 return prcm_irq_setup->base_irq +
161 prcm_irq_setup->irqs[i].offset;
162
163 return -ENOENT;
164}
165
166/**
167 * omap_prcm_irq_cleanup - reverses memory allocated and other steps
168 * done by omap_prcm_register_chain_handler()
169 *
170 * No return value.
171 */
172void omap_prcm_irq_cleanup(void)
173{
174 int i;
175
176 if (!prcm_irq_setup) {
177 pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n");
178 return;
179 }
180
181 if (prcm_irq_chips) {
182 for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
183 if (prcm_irq_chips[i])
184 irq_remove_generic_chip(prcm_irq_chips[i],
185 0xffffffff, 0, 0);
186 prcm_irq_chips[i] = NULL;
187 }
188 kfree(prcm_irq_chips);
189 prcm_irq_chips = NULL;
190 }
191
192 kfree(prcm_irq_setup->saved_mask);
193 prcm_irq_setup->saved_mask = NULL;
194
195 kfree(prcm_irq_setup->priority_mask);
196 prcm_irq_setup->priority_mask = NULL;
197
198 irq_set_chained_handler(prcm_irq_setup->irq, NULL);
199
200 if (prcm_irq_setup->base_irq > 0)
201 irq_free_descs(prcm_irq_setup->base_irq,
202 prcm_irq_setup->nr_regs * 32);
203 prcm_irq_setup->base_irq = 0;
204}
205
206void omap_prcm_irq_prepare(void)
207{
208 prcm_irq_setup->suspended = true;
209}
210
211void omap_prcm_irq_complete(void)
212{
213 prcm_irq_setup->suspended = false;
214
215 /* If we have not saved the masks, do not attempt to restore */
216 if (!prcm_irq_setup->suspend_save_flag)
217 return;
218
219 prcm_irq_setup->suspend_save_flag = false;
220
221 /*
222 * Re-enable all masked PRCM irq sources, this causes the PRCM
223 * interrupt to fire immediately if the events were masked
224 * previously in the chain handler
225 */
226 prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask);
227}
228
229/**
230 * omap_prcm_register_chain_handler - initializes the prcm chained interrupt
231 * handler based on provided parameters
232 * @irq_setup: hardware data about the underlying PRM/PRCM
233 *
234 * Set up the PRCM chained interrupt handler on the PRCM IRQ. Sets up
235 * one generic IRQ chip per PRM interrupt status/enable register pair.
236 * Returns 0 upon success, -EINVAL if called twice or if invalid
237 * arguments are passed, or -ENOMEM on any other error.
238 */
239int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
240{
241 int nr_regs = irq_setup->nr_regs;
242 u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
243 int offset, i;
244 struct irq_chip_generic *gc;
245 struct irq_chip_type *ct;
246
247 if (!irq_setup)
248 return -EINVAL;
249
250 if (prcm_irq_setup) {
251 pr_err("PRCM: already initialized; won't reinitialize\n");
252 return -EINVAL;
253 }
254
255 if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
256 pr_err("PRCM: nr_regs too large\n");
257 return -EINVAL;
258 }
259
260 prcm_irq_setup = irq_setup;
261
262 prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
263 prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
264 prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
265 GFP_KERNEL);
266
267 if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
268 !prcm_irq_setup->priority_mask) {
269 pr_err("PRCM: kzalloc failed\n");
270 goto err;
271 }
272
273 memset(mask, 0, sizeof(mask));
274
275 for (i = 0; i < irq_setup->nr_irqs; i++) {
276 offset = irq_setup->irqs[i].offset;
277 mask[offset >> 5] |= 1 << (offset & 0x1f);
278 if (irq_setup->irqs[i].priority)
279 irq_setup->priority_mask[offset >> 5] |=
280 1 << (offset & 0x1f);
281 }
282
283 irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);
284
285 irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
286 0);
287
288 if (irq_setup->base_irq < 0) {
289 pr_err("PRCM: failed to allocate irq descs: %d\n",
290 irq_setup->base_irq);
291 goto err;
292 }
293
294 for (i = 0; i <= irq_setup->nr_regs; i++) {
295 gc = irq_alloc_generic_chip("PRCM", 1,
296 irq_setup->base_irq + i * 32, prm_base,
297 handle_level_irq);
298
299 if (!gc) {
300 pr_err("PRCM: failed to allocate generic chip\n");
301 goto err;
302 }
303 ct = gc->chip_types;
304 ct->chip.irq_ack = irq_gc_ack_set_bit;
305 ct->chip.irq_mask = irq_gc_mask_clr_bit;
306 ct->chip.irq_unmask = irq_gc_mask_set_bit;
307
308 ct->regs.ack = irq_setup->ack + i * 4;
309 ct->regs.mask = irq_setup->mask + i * 4;
310
311 irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
312 prcm_irq_chips[i] = gc;
313 }
314
315 return 0;
316
317err:
318 omap_prcm_irq_cleanup();
319 return -ENOMEM;
320}
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index d0f009cbfb50..247d89478f24 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -19,26 +19,21 @@
19 */ 19 */
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/serial_reg.h>
23#include <linux/clk.h> 22#include <linux/clk.h>
24#include <linux/io.h> 23#include <linux/io.h>
25#include <linux/delay.h> 24#include <linux/delay.h>
26#include <linux/platform_device.h> 25#include <linux/platform_device.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
28#include <linux/serial_8250.h>
29#include <linux/pm_runtime.h> 27#include <linux/pm_runtime.h>
30#include <linux/console.h> 28#include <linux/console.h>
31 29
32#ifdef CONFIG_SERIAL_OMAP
33#include <plat/omap-serial.h> 30#include <plat/omap-serial.h>
34#endif
35
36#include "common.h" 31#include "common.h"
37#include <plat/board.h> 32#include <plat/board.h>
38#include <plat/clock.h>
39#include <plat/dma.h> 33#include <plat/dma.h>
40#include <plat/omap_hwmod.h> 34#include <plat/omap_hwmod.h>
41#include <plat/omap_device.h> 35#include <plat/omap_device.h>
36#include <plat/omap-pm.h>
42 37
43#include "prm2xxx_3xxx.h" 38#include "prm2xxx_3xxx.h"
44#include "pm.h" 39#include "pm.h"
@@ -47,603 +42,226 @@
47#include "control.h" 42#include "control.h"
48#include "mux.h" 43#include "mux.h"
49 44
50#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
51#define UART_OMAP_WER 0x17 /* Wake-up enable register */
52
53#define UART_ERRATA_FIFO_FULL_ABORT (0x1 << 0)
54#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1)
55
56/* 45/*
57 * NOTE: By default the serial timeout is disabled as it causes lost characters 46 * NOTE: By default the serial auto_suspend timeout is disabled as it causes
58 * over the serial ports. This means that the UART clocks will stay on until 47 * lost characters over the serial ports. This means that the UART clocks will
59 * disabled via sysfs. This also causes that any deeper omap sleep states are 48 * stay on until power/autosuspend_delay is set for the uart from sysfs.
60 * blocked. 49 * This also causes that any deeper omap sleep states are blocked.
61 */ 50 */
62#define DEFAULT_TIMEOUT 0 51#define DEFAULT_AUTOSUSPEND_DELAY -1
63 52
64#define MAX_UART_HWMOD_NAME_LEN 16 53#define MAX_UART_HWMOD_NAME_LEN 16
65 54
66struct omap_uart_state { 55struct omap_uart_state {
67 int num; 56 int num;
68 int can_sleep; 57 int can_sleep;
69 struct timer_list timer;
70 u32 timeout;
71
72 void __iomem *wk_st;
73 void __iomem *wk_en;
74 u32 wk_mask;
75 u32 padconf;
76 u32 dma_enabled;
77
78 struct clk *ick;
79 struct clk *fck;
80 int clocked;
81
82 int irq;
83 int regshift;
84 int irqflags;
85 void __iomem *membase;
86 resource_size_t mapbase;
87 58
88 struct list_head node; 59 struct list_head node;
89 struct omap_hwmod *oh; 60 struct omap_hwmod *oh;
90 struct platform_device *pdev; 61 struct platform_device *pdev;
91
92 u32 errata;
93#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
94 int context_valid;
95
96 /* Registers to be saved/restored for OFF-mode */
97 u16 dll;
98 u16 dlh;
99 u16 ier;
100 u16 sysc;
101 u16 scr;
102 u16 wer;
103 u16 mcr;
104#endif
105}; 62};
106 63
107static LIST_HEAD(uart_list); 64static LIST_HEAD(uart_list);
108static u8 num_uarts; 65static u8 num_uarts;
66static u8 console_uart_id = -1;
67static u8 no_console_suspend;
68static u8 uart_debug;
69
70#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */
71#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */
72#define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */
73
74static struct omap_uart_port_info omap_serial_default_info[] __initdata = {
75 {
76 .dma_enabled = false,
77 .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
78 .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
79 .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
80 .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY,
81 },
82};
109 83
110static inline unsigned int __serial_read_reg(struct uart_port *up, 84#ifdef CONFIG_PM
111 int offset) 85static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
112{
113 offset <<= up->regshift;
114 return (unsigned int)__raw_readb(up->membase + offset);
115}
116
117static inline unsigned int serial_read_reg(struct omap_uart_state *uart,
118 int offset)
119{ 86{
120 offset <<= uart->regshift; 87 struct omap_device *od = to_omap_device(pdev);
121 return (unsigned int)__raw_readb(uart->membase + offset);
122}
123 88
124static inline void __serial_write_reg(struct uart_port *up, int offset, 89 if (!od)
125 int value) 90 return;
126{
127 offset <<= up->regshift;
128 __raw_writeb(value, up->membase + offset);
129}
130 91
131static inline void serial_write_reg(struct omap_uart_state *uart, int offset, 92 if (enable)
132 int value) 93 omap_hwmod_enable_wakeup(od->hwmods[0]);
133{ 94 else
134 offset <<= uart->regshift; 95 omap_hwmod_disable_wakeup(od->hwmods[0]);
135 __raw_writeb(value, uart->membase + offset);
136} 96}
137 97
138/* 98/*
139 * Internal UARTs need to be initialized for the 8250 autoconfig to work 99 * Errata i291: [UART]:Cannot Acknowledge Idle Requests
140 * properly. Note that the TX watermark initialization may not be needed 100 * in Smartidle Mode When Configured for DMA Operations.
141 * once the 8250.c watermark handling code is merged. 101 * WA: configure uart in force idle mode.
142 */ 102 */
143 103static void omap_uart_set_noidle(struct platform_device *pdev)
144static inline void __init omap_uart_reset(struct omap_uart_state *uart)
145{ 104{
146 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); 105 struct omap_device *od = to_omap_device(pdev);
147 serial_write_reg(uart, UART_OMAP_SCR, 0x08);
148 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
149}
150
151#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
152 106
153/* 107 omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
154 * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
155 * The access to uart register after MDR1 Access
156 * causes UART to corrupt data.
157 *
158 * Need a delay =
159 * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
160 * give 10 times as much
161 */
162static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
163 u8 fcr_val)
164{
165 u8 timeout = 255;
166
167 serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val);
168 udelay(2);
169 serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
170 UART_FCR_CLEAR_RCVR);
171 /*
172 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
173 * TX_FIFO_E bit is 1.
174 */
175 while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) &
176 (UART_LSR_THRE | UART_LSR_DR))) {
177 timeout--;
178 if (!timeout) {
179 /* Should *never* happen. we warn and carry on */
180 dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n",
181 serial_read_reg(uart, UART_LSR));
182 break;
183 }
184 udelay(1);
185 }
186} 108}
187 109
188static void omap_uart_save_context(struct omap_uart_state *uart) 110static void omap_uart_set_forceidle(struct platform_device *pdev)
189{ 111{
190 u16 lcr = 0; 112 struct omap_device *od = to_omap_device(pdev);
191 113
192 if (!enable_off_mode) 114 omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE);
193 return;
194
195 lcr = serial_read_reg(uart, UART_LCR);
196 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
197 uart->dll = serial_read_reg(uart, UART_DLL);
198 uart->dlh = serial_read_reg(uart, UART_DLM);
199 serial_write_reg(uart, UART_LCR, lcr);
200 uart->ier = serial_read_reg(uart, UART_IER);
201 uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
202 uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
203 uart->wer = serial_read_reg(uart, UART_OMAP_WER);
204 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
205 uart->mcr = serial_read_reg(uart, UART_MCR);
206 serial_write_reg(uart, UART_LCR, lcr);
207
208 uart->context_valid = 1;
209} 115}
210 116
211static void omap_uart_restore_context(struct omap_uart_state *uart)
212{
213 u16 efr = 0;
214
215 if (!enable_off_mode)
216 return;
217
218 if (!uart->context_valid)
219 return;
220
221 uart->context_valid = 0;
222
223 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
224 omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0);
225 else
226 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
227
228 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
229 efr = serial_read_reg(uart, UART_EFR);
230 serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
231 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
232 serial_write_reg(uart, UART_IER, 0x0);
233 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
234 serial_write_reg(uart, UART_DLL, uart->dll);
235 serial_write_reg(uart, UART_DLM, uart->dlh);
236 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
237 serial_write_reg(uart, UART_IER, uart->ier);
238 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
239 serial_write_reg(uart, UART_MCR, uart->mcr);
240 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
241 serial_write_reg(uart, UART_EFR, efr);
242 serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
243 serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
244 serial_write_reg(uart, UART_OMAP_WER, uart->wer);
245 serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
246
247 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
248 omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1);
249 else
250 /* UART 16x mode */
251 serial_write_reg(uart, UART_OMAP_MDR1,
252 UART_OMAP_MDR1_16X_MODE);
253}
254#else 117#else
255static inline void omap_uart_save_context(struct omap_uart_state *uart) {} 118static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
256static inline void omap_uart_restore_context(struct omap_uart_state *uart) {} 119{}
257#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */ 120static void omap_uart_set_noidle(struct platform_device *pdev) {}
258 121static void omap_uart_set_forceidle(struct platform_device *pdev) {}
259static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) 122#endif /* CONFIG_PM */
260{
261 if (uart->clocked)
262 return;
263
264 omap_device_enable(uart->pdev);
265 uart->clocked = 1;
266 omap_uart_restore_context(uart);
267}
268
269#ifdef CONFIG_PM
270
271static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
272{
273 if (!uart->clocked)
274 return;
275
276 omap_uart_save_context(uart);
277 uart->clocked = 0;
278 omap_device_idle(uart->pdev);
279}
280
281static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
282{
283 /* Set wake-enable bit */
284 if (uart->wk_en && uart->wk_mask) {
285 u32 v = __raw_readl(uart->wk_en);
286 v |= uart->wk_mask;
287 __raw_writel(v, uart->wk_en);
288 }
289
290 /* Ensure IOPAD wake-enables are set */
291 if (cpu_is_omap34xx() && uart->padconf) {
292 u16 v = omap_ctrl_readw(uart->padconf);
293 v |= OMAP3_PADCONF_WAKEUPENABLE0;
294 omap_ctrl_writew(v, uart->padconf);
295 }
296}
297
298static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
299{
300 /* Clear wake-enable bit */
301 if (uart->wk_en && uart->wk_mask) {
302 u32 v = __raw_readl(uart->wk_en);
303 v &= ~uart->wk_mask;
304 __raw_writel(v, uart->wk_en);
305 }
306
307 /* Ensure IOPAD wake-enables are cleared */
308 if (cpu_is_omap34xx() && uart->padconf) {
309 u16 v = omap_ctrl_readw(uart->padconf);
310 v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
311 omap_ctrl_writew(v, uart->padconf);
312 }
313}
314
315static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
316 int enable)
317{
318 u8 idlemode;
319
320 if (enable) {
321 /**
322 * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
323 * in Smartidle Mode When Configured for DMA Operations.
324 */
325 if (uart->dma_enabled)
326 idlemode = HWMOD_IDLEMODE_FORCE;
327 else
328 idlemode = HWMOD_IDLEMODE_SMART;
329 } else {
330 idlemode = HWMOD_IDLEMODE_NO;
331 }
332
333 omap_hwmod_set_slave_idlemode(uart->oh, idlemode);
334}
335
336static void omap_uart_block_sleep(struct omap_uart_state *uart)
337{
338 omap_uart_enable_clocks(uart);
339
340 omap_uart_smart_idle_enable(uart, 0);
341 uart->can_sleep = 0;
342 if (uart->timeout)
343 mod_timer(&uart->timer, jiffies + uart->timeout);
344 else
345 del_timer(&uart->timer);
346}
347
348static void omap_uart_allow_sleep(struct omap_uart_state *uart)
349{
350 if (device_may_wakeup(&uart->pdev->dev))
351 omap_uart_enable_wakeup(uart);
352 else
353 omap_uart_disable_wakeup(uart);
354
355 if (!uart->clocked)
356 return;
357
358 omap_uart_smart_idle_enable(uart, 1);
359 uart->can_sleep = 1;
360 del_timer(&uart->timer);
361}
362
363static void omap_uart_idle_timer(unsigned long data)
364{
365 struct omap_uart_state *uart = (struct omap_uart_state *)data;
366
367 omap_uart_allow_sleep(uart);
368}
369
370void omap_uart_prepare_idle(int num)
371{
372 struct omap_uart_state *uart;
373
374 list_for_each_entry(uart, &uart_list, node) {
375 if (num == uart->num && uart->can_sleep) {
376 omap_uart_disable_clocks(uart);
377 return;
378 }
379 }
380}
381
382void omap_uart_resume_idle(int num)
383{
384 struct omap_uart_state *uart;
385
386 list_for_each_entry(uart, &uart_list, node) {
387 if (num == uart->num && uart->can_sleep) {
388 omap_uart_enable_clocks(uart);
389
390 /* Check for IO pad wakeup */
391 if (cpu_is_omap34xx() && uart->padconf) {
392 u16 p = omap_ctrl_readw(uart->padconf);
393
394 if (p & OMAP3_PADCONF_WAKEUPEVENT0)
395 omap_uart_block_sleep(uart);
396 }
397
398 /* Check for normal UART wakeup */
399 if (__raw_readl(uart->wk_st) & uart->wk_mask)
400 omap_uart_block_sleep(uart);
401 return;
402 }
403 }
404}
405
406void omap_uart_prepare_suspend(void)
407{
408 struct omap_uart_state *uart;
409
410 list_for_each_entry(uart, &uart_list, node) {
411 omap_uart_allow_sleep(uart);
412 }
413}
414
415int omap_uart_can_sleep(void)
416{
417 struct omap_uart_state *uart;
418 int can_sleep = 1;
419
420 list_for_each_entry(uart, &uart_list, node) {
421 if (!uart->clocked)
422 continue;
423
424 if (!uart->can_sleep) {
425 can_sleep = 0;
426 continue;
427 }
428
429 /* This UART can now safely sleep. */
430 omap_uart_allow_sleep(uart);
431 }
432
433 return can_sleep;
434}
435 123
436/** 124#ifdef CONFIG_OMAP_MUX
437 * omap_uart_interrupt() 125static struct omap_device_pad default_uart1_pads[] __initdata = {
438 * 126 {
439 * This handler is used only to detect that *any* UART interrupt has 127 .name = "uart1_cts.uart1_cts",
440 * occurred. It does _nothing_ to handle the interrupt. Rather, 128 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
441 * any UART interrupt will trigger the inactivity timer so the 129 },
442 * UART will not idle or sleep for its timeout period. 130 {
443 * 131 .name = "uart1_rts.uart1_rts",
444 **/ 132 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
445/* static int first_interrupt; */ 133 },
446static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) 134 {
447{ 135 .name = "uart1_tx.uart1_tx",
448 struct omap_uart_state *uart = dev_id; 136 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
137 },
138 {
139 .name = "uart1_rx.uart1_rx",
140 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
141 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
142 .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
143 },
144};
449 145
450 omap_uart_block_sleep(uart); 146static struct omap_device_pad default_uart2_pads[] __initdata = {
147 {
148 .name = "uart2_cts.uart2_cts",
149 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
150 },
151 {
152 .name = "uart2_rts.uart2_rts",
153 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
154 },
155 {
156 .name = "uart2_tx.uart2_tx",
157 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
158 },
159 {
160 .name = "uart2_rx.uart2_rx",
161 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
162 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
163 .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
164 },
165};
451 166
452 return IRQ_NONE; 167static struct omap_device_pad default_uart3_pads[] __initdata = {
453} 168 {
169 .name = "uart3_cts_rctx.uart3_cts_rctx",
170 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
171 },
172 {
173 .name = "uart3_rts_sd.uart3_rts_sd",
174 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
175 },
176 {
177 .name = "uart3_tx_irtx.uart3_tx_irtx",
178 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
179 },
180 {
181 .name = "uart3_rx_irrx.uart3_rx_irrx",
182 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
183 .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
184 .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
185 },
186};
454 187
455static void omap_uart_idle_init(struct omap_uart_state *uart) 188static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
456{ 189 {
457 int ret; 190 .name = "gpmc_wait2.uart4_tx",
458 191 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
459 uart->can_sleep = 0; 192 },
460 uart->timeout = DEFAULT_TIMEOUT; 193 {
461 setup_timer(&uart->timer, omap_uart_idle_timer, 194 .name = "gpmc_wait3.uart4_rx",
462 (unsigned long) uart); 195 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
463 if (uart->timeout) 196 .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
464 mod_timer(&uart->timer, jiffies + uart->timeout); 197 .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
465 omap_uart_smart_idle_enable(uart, 0); 198 },
466 199};
467 if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) {
468 u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
469 u32 wk_mask = 0;
470 u32 padconf = 0;
471
472 /* XXX These PRM accesses do not belong here */
473 uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
474 uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
475 switch (uart->num) {
476 case 0:
477 wk_mask = OMAP3430_ST_UART1_MASK;
478 padconf = 0x182;
479 break;
480 case 1:
481 wk_mask = OMAP3430_ST_UART2_MASK;
482 padconf = 0x17a;
483 break;
484 case 2:
485 wk_mask = OMAP3430_ST_UART3_MASK;
486 padconf = 0x19e;
487 break;
488 case 3:
489 wk_mask = OMAP3630_ST_UART4_MASK;
490 padconf = 0x0d2;
491 break;
492 }
493 uart->wk_mask = wk_mask;
494 uart->padconf = padconf;
495 } else if (cpu_is_omap24xx()) {
496 u32 wk_mask = 0;
497 u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
498
499 switch (uart->num) {
500 case 0:
501 wk_mask = OMAP24XX_ST_UART1_MASK;
502 break;
503 case 1:
504 wk_mask = OMAP24XX_ST_UART2_MASK;
505 break;
506 case 2:
507 wk_en = OMAP24XX_PM_WKEN2;
508 wk_st = OMAP24XX_PM_WKST2;
509 wk_mask = OMAP24XX_ST_UART3_MASK;
510 break;
511 }
512 uart->wk_mask = wk_mask;
513 if (cpu_is_omap2430()) {
514 uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en);
515 uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st);
516 } else if (cpu_is_omap2420()) {
517 uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en);
518 uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st);
519 }
520 } else {
521 uart->wk_en = NULL;
522 uart->wk_st = NULL;
523 uart->wk_mask = 0;
524 uart->padconf = 0;
525 }
526 200
527 uart->irqflags |= IRQF_SHARED; 201static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
528 ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt, 202 {
529 IRQF_SHARED, "serial idle", (void *)uart); 203 .name = "uart4_tx.uart4_tx",
530 WARN_ON(ret); 204 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
531} 205 },
206 {
207 .name = "uart4_rx.uart4_rx",
208 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
209 .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
210 .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
211 },
212};
532 213
533void omap_uart_enable_irqs(int enable) 214static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
534{ 215{
535 int ret; 216 switch (bdata->id) {
536 struct omap_uart_state *uart; 217 case 0:
537 218 bdata->pads = default_uart1_pads;
538 list_for_each_entry(uart, &uart_list, node) { 219 bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads);
539 if (enable) { 220 break;
540 pm_runtime_put_sync(&uart->pdev->dev); 221 case 1:
541 ret = request_threaded_irq(uart->irq, NULL, 222 bdata->pads = default_uart2_pads;
542 omap_uart_interrupt, 223 bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads);
543 IRQF_SHARED, 224 break;
544 "serial idle", 225 case 2:
545 (void *)uart); 226 bdata->pads = default_uart3_pads;
546 } else { 227 bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads);
547 pm_runtime_get_noresume(&uart->pdev->dev); 228 break;
548 free_irq(uart->irq, (void *)uart); 229 case 3:
230 if (cpu_is_omap44xx()) {
231 bdata->pads = default_omap4_uart4_pads;
232 bdata->pads_cnt =
233 ARRAY_SIZE(default_omap4_uart4_pads);
234 } else if (cpu_is_omap3630()) {
235 bdata->pads = default_omap36xx_uart4_pads;
236 bdata->pads_cnt =
237 ARRAY_SIZE(default_omap36xx_uart4_pads);
549 } 238 }
239 break;
240 default:
241 break;
550 } 242 }
551} 243}
552
553static ssize_t sleep_timeout_show(struct device *dev,
554 struct device_attribute *attr,
555 char *buf)
556{
557 struct platform_device *pdev = to_platform_device(dev);
558 struct omap_device *odev = to_omap_device(pdev);
559 struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
560
561 return sprintf(buf, "%u\n", uart->timeout / HZ);
562}
563
564static ssize_t sleep_timeout_store(struct device *dev,
565 struct device_attribute *attr,
566 const char *buf, size_t n)
567{
568 struct platform_device *pdev = to_platform_device(dev);
569 struct omap_device *odev = to_omap_device(pdev);
570 struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
571 unsigned int value;
572
573 if (sscanf(buf, "%u", &value) != 1) {
574 dev_err(dev, "sleep_timeout_store: Invalid value\n");
575 return -EINVAL;
576 }
577
578 uart->timeout = value * HZ;
579 if (uart->timeout)
580 mod_timer(&uart->timer, jiffies + uart->timeout);
581 else
582 /* A zero value means disable timeout feature */
583 omap_uart_block_sleep(uart);
584
585 return n;
586}
587
588static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
589 sleep_timeout_store);
590#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
591#else 244#else
592static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} 245static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
593static void omap_uart_block_sleep(struct omap_uart_state *uart) 246#endif
594{
595 /* Needed to enable UART clocks when built without CONFIG_PM */
596 omap_uart_enable_clocks(uart);
597}
598#define DEV_CREATE_FILE(dev, attr)
599#endif /* CONFIG_PM */
600
601#ifndef CONFIG_SERIAL_OMAP
602/*
603 * Override the default 8250 read handler: mem_serial_in()
604 * Empty RX fifo read causes an abort on omap3630 and omap4
605 * This function makes sure that an empty rx fifo is not read on these silicons
606 * (OMAP1/2/3430 are not affected)
607 */
608static unsigned int serial_in_override(struct uart_port *up, int offset)
609{
610 if (UART_RX == offset) {
611 unsigned int lsr;
612 lsr = __serial_read_reg(up, UART_LSR);
613 if (!(lsr & UART_LSR_DR))
614 return -EPERM;
615 }
616
617 return __serial_read_reg(up, offset);
618}
619 247
620static void serial_out_override(struct uart_port *up, int offset, int value) 248char *cmdline_find_option(char *str)
621{ 249{
622 unsigned int status, tmout = 10000; 250 extern char *saved_command_line;
623 251
624 status = __serial_read_reg(up, UART_LSR); 252 return strstr(saved_command_line, str);
625 while (!(status & UART_LSR_THRE)) {
626 /* Wait up to 10ms for the character(s) to be sent. */
627 if (--tmout == 0)
628 break;
629 udelay(1);
630 status = __serial_read_reg(up, UART_LSR);
631 }
632 __serial_write_reg(up, offset, value);
633} 253}
634#endif
635 254
636static int __init omap_serial_early_init(void) 255static int __init omap_serial_early_init(void)
637{ 256{
638 int i = 0;
639
640 do { 257 do {
641 char oh_name[MAX_UART_HWMOD_NAME_LEN]; 258 char oh_name[MAX_UART_HWMOD_NAME_LEN];
642 struct omap_hwmod *oh; 259 struct omap_hwmod *oh;
643 struct omap_uart_state *uart; 260 struct omap_uart_state *uart;
261 char uart_name[MAX_UART_HWMOD_NAME_LEN];
644 262
645 snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, 263 snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
646 "uart%d", i + 1); 264 "uart%d", num_uarts + 1);
647 oh = omap_hwmod_lookup(oh_name); 265 oh = omap_hwmod_lookup(oh_name);
648 if (!oh) 266 if (!oh)
649 break; 267 break;
@@ -653,21 +271,35 @@ static int __init omap_serial_early_init(void)
653 return -ENODEV; 271 return -ENODEV;
654 272
655 uart->oh = oh; 273 uart->oh = oh;
656 uart->num = i++; 274 uart->num = num_uarts++;
657 list_add_tail(&uart->node, &uart_list); 275 list_add_tail(&uart->node, &uart_list);
658 num_uarts++; 276 snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN,
659 277 "%s%d", OMAP_SERIAL_NAME, uart->num);
660 /* 278
661 * NOTE: omap_hwmod_setup*() has not yet been called, 279 if (cmdline_find_option(uart_name)) {
662 * so no hwmod functions will work yet. 280 console_uart_id = uart->num;
663 */ 281
664 282 if (console_loglevel >= 10) {
665 /* 283 uart_debug = true;
666 * During UART early init, device need to be probed 284 pr_info("%s used as console in debug mode"
667 * to determine SoC specific init before omap_device 285 " uart%d clocks will not be"
668 * is ready. Therefore, don't allow idle here 286 " gated", uart_name, uart->num);
669 */ 287 }
670 uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET; 288
289 if (cmdline_find_option("no_console_suspend"))
290 no_console_suspend = true;
291
292 /*
293 * omap-uart can be used for earlyprintk logs
294 * So if omap-uart is used as console then prevent
295 * uart reset and idle to get logs from omap-uart
296 * until uart console driver is available to take
297 * care for console messages.
298 * Idling or resetting omap-uart while printing logs
299 * early boot logs can stall the boot-up.
300 */
301 oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
302 }
671 } while (1); 303 } while (1);
672 304
673 return 0; 305 return 0;
@@ -677,6 +309,7 @@ core_initcall(omap_serial_early_init);
677/** 309/**
678 * omap_serial_init_port() - initialize single serial port 310 * omap_serial_init_port() - initialize single serial port
679 * @bdata: port specific board data pointer 311 * @bdata: port specific board data pointer
312 * @info: platform specific data pointer
680 * 313 *
681 * This function initialies serial driver for given port only. 314 * This function initialies serial driver for given port only.
682 * Platforms can call this function instead of omap_serial_init() 315 * Platforms can call this function instead of omap_serial_init()
@@ -685,7 +318,8 @@ core_initcall(omap_serial_early_init);
685 * Don't mix calls to omap_serial_init_port() and omap_serial_init(), 318 * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
686 * use only one of the two. 319 * use only one of the two.
687 */ 320 */
688void __init omap_serial_init_port(struct omap_board_data *bdata) 321void __init omap_serial_init_port(struct omap_board_data *bdata,
322 struct omap_uart_port_info *info)
689{ 323{
690 struct omap_uart_state *uart; 324 struct omap_uart_state *uart;
691 struct omap_hwmod *oh; 325 struct omap_hwmod *oh;
@@ -693,15 +327,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
693 void *pdata = NULL; 327 void *pdata = NULL;
694 u32 pdata_size = 0; 328 u32 pdata_size = 0;
695 char *name; 329 char *name;
696#ifndef CONFIG_SERIAL_OMAP
697 struct plat_serial8250_port ports[2] = {
698 {},
699 {.flags = 0},
700 };
701 struct plat_serial8250_port *p = &ports[0];
702#else
703 struct omap_uart_port_info omap_up; 330 struct omap_uart_port_info omap_up;
704#endif
705 331
706 if (WARN_ON(!bdata)) 332 if (WARN_ON(!bdata))
707 return; 333 return;
@@ -713,66 +339,34 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
713 list_for_each_entry(uart, &uart_list, node) 339 list_for_each_entry(uart, &uart_list, node)
714 if (bdata->id == uart->num) 340 if (bdata->id == uart->num)
715 break; 341 break;
342 if (!info)
343 info = omap_serial_default_info;
716 344
717 oh = uart->oh; 345 oh = uart->oh;
718 uart->dma_enabled = 0;
719#ifndef CONFIG_SERIAL_OMAP
720 name = "serial8250";
721
722 /*
723 * !! 8250 driver does not use standard IORESOURCE* It
724 * has it's own custom pdata that can be taken from
725 * the hwmod resource data. But, this needs to be
726 * done after the build.
727 *
728 * ?? does it have to be done before the register ??
729 * YES, because platform_device_data_add() copies
730 * pdata, it does not use a pointer.
731 */
732 p->flags = UPF_BOOT_AUTOCONF;
733 p->iotype = UPIO_MEM;
734 p->regshift = 2;
735 p->uartclk = OMAP24XX_BASE_BAUD * 16;
736 p->irq = oh->mpu_irqs[0].irq;
737 p->mapbase = oh->slaves[0]->addr->pa_start;
738 p->membase = omap_hwmod_get_mpu_rt_va(oh);
739 p->irqflags = IRQF_SHARED;
740 p->private_data = uart;
741
742 /*
743 * omap44xx, ti816x: Never read empty UART fifo
744 * omap3xxx: Never read empty UART fifo on UARTs
745 * with IP rev >=0x52
746 */
747 uart->regshift = p->regshift;
748 uart->membase = p->membase;
749 if (cpu_is_omap44xx() || cpu_is_ti81xx())
750 uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
751 else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF)
752 >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
753 uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
754
755 if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
756 p->serial_in = serial_in_override;
757 p->serial_out = serial_out_override;
758 }
759
760 pdata = &ports[0];
761 pdata_size = 2 * sizeof(struct plat_serial8250_port);
762#else
763
764 name = DRIVER_NAME; 346 name = DRIVER_NAME;
765 347
766 omap_up.dma_enabled = uart->dma_enabled; 348 omap_up.dma_enabled = info->dma_enabled;
767 omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; 349 omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
768 omap_up.mapbase = oh->slaves[0]->addr->pa_start; 350 omap_up.flags = UPF_BOOT_AUTOCONF;
769 omap_up.membase = omap_hwmod_get_mpu_rt_va(oh); 351 omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
770 omap_up.irqflags = IRQF_SHARED; 352 omap_up.set_forceidle = omap_uart_set_forceidle;
771 omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; 353 omap_up.set_noidle = omap_uart_set_noidle;
354 omap_up.enable_wakeup = omap_uart_enable_wakeup;
355 omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
356 omap_up.dma_rx_timeout = info->dma_rx_timeout;
357 omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate;
358 omap_up.autosuspend_timeout = info->autosuspend_timeout;
359
360 /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */
361 if (!cpu_is_omap2420() && !cpu_is_ti816x())
362 omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS;
363
364 /* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */
365 if (cpu_is_omap34xx() || cpu_is_omap3630())
366 omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE;
772 367
773 pdata = &omap_up; 368 pdata = &omap_up;
774 pdata_size = sizeof(struct omap_uart_port_info); 369 pdata_size = sizeof(struct omap_uart_port_info);
775#endif
776 370
777 if (WARN_ON(!oh)) 371 if (WARN_ON(!oh))
778 return; 372 return;
@@ -782,64 +376,29 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
782 WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", 376 WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
783 name, oh->name); 377 name, oh->name);
784 378
785 omap_device_disable_idle_on_suspend(pdev); 379 if ((console_uart_id == bdata->id) && no_console_suspend)
380 omap_device_disable_idle_on_suspend(pdev);
381
786 oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); 382 oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
787 383
788 uart->irq = oh->mpu_irqs[0].irq;
789 uart->regshift = 2;
790 uart->mapbase = oh->slaves[0]->addr->pa_start;
791 uart->membase = omap_hwmod_get_mpu_rt_va(oh);
792 uart->pdev = pdev; 384 uart->pdev = pdev;
793 385
794 oh->dev_attr = uart; 386 oh->dev_attr = uart;
795 387
796 console_lock(); /* in case the earlycon is on the UART */ 388 if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
797 389 && !uart_debug)
798 /*
799 * Because of early UART probing, UART did not get idled
800 * on init. Now that omap_device is ready, ensure full idle
801 * before doing omap_device_enable().
802 */
803 omap_hwmod_idle(uart->oh);
804
805 omap_device_enable(uart->pdev);
806 omap_uart_idle_init(uart);
807 omap_uart_reset(uart);
808 omap_hwmod_enable_wakeup(uart->oh);
809 omap_device_idle(uart->pdev);
810
811 /*
812 * Need to block sleep long enough for interrupt driven
813 * driver to start. Console driver is in polling mode
814 * so device needs to be kept enabled while polling driver
815 * is in use.
816 */
817 if (uart->timeout)
818 uart->timeout = (30 * HZ);
819 omap_uart_block_sleep(uart);
820 uart->timeout = DEFAULT_TIMEOUT;
821
822 console_unlock();
823
824 if ((cpu_is_omap34xx() && uart->padconf) ||
825 (uart->wk_en && uart->wk_mask)) {
826 device_init_wakeup(&pdev->dev, true); 390 device_init_wakeup(&pdev->dev, true);
827 DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout);
828 }
829
830 /* Enable the MDR1 errata for OMAP3 */
831 if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx()))
832 uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
833} 391}
834 392
835/** 393/**
836 * omap_serial_init() - initialize all supported serial ports 394 * omap_serial_board_init() - initialize all supported serial ports
395 * @info: platform specific data pointer
837 * 396 *
838 * Initializes all available UARTs as serial ports. Platforms 397 * Initializes all available UARTs as serial ports. Platforms
839 * can call this function when they want to have default behaviour 398 * can call this function when they want to have default behaviour
840 * for serial ports (e.g initialize them all as serial ports). 399 * for serial ports (e.g initialize them all as serial ports).
841 */ 400 */
842void __init omap_serial_init(void) 401void __init omap_serial_board_init(struct omap_uart_port_info *info)
843{ 402{
844 struct omap_uart_state *uart; 403 struct omap_uart_state *uart;
845 struct omap_board_data bdata; 404 struct omap_board_data bdata;
@@ -849,7 +408,25 @@ void __init omap_serial_init(void)
849 bdata.flags = 0; 408 bdata.flags = 0;
850 bdata.pads = NULL; 409 bdata.pads = NULL;
851 bdata.pads_cnt = 0; 410 bdata.pads_cnt = 0;
852 omap_serial_init_port(&bdata);
853 411
412 if (cpu_is_omap44xx() || cpu_is_omap34xx())
413 omap_serial_fill_default_pads(&bdata);
414
415 if (!info)
416 omap_serial_init_port(&bdata, NULL);
417 else
418 omap_serial_init_port(&bdata, &info[uart->num]);
854 } 419 }
855} 420}
421
422/**
423 * omap_serial_init() - initialize all supported serial ports
424 *
425 * Initializes all available UARTs.
426 * Platforms can call this function when they want to have default behaviour
427 * for serial ports (e.g initialize them all as serial ports).
428 */
429void __init omap_serial_init(void)
430{
431 omap_serial_board_init(NULL);
432}
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
new file mode 100644
index 000000000000..abd283400490
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -0,0 +1,379 @@
1/*
2 * OMAP44xx sleep code.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
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/linkage.h>
13#include <asm/system.h>
14#include <asm/smp_scu.h>
15#include <asm/memory.h>
16#include <asm/hardware/cache-l2x0.h>
17
18#include <plat/omap44xx.h>
19#include <mach/omap-secure.h>
20
21#include "common.h"
22#include "omap4-sar-layout.h"
23
24#if defined(CONFIG_SMP) && defined(CONFIG_PM)
25
26.macro DO_SMC
27 dsb
28 smc #0
29 dsb
30.endm
31
32ppa_zero_params:
33 .word 0x0
34
35ppa_por_params:
36 .word 1, 0
37
38/*
39 * =============================
40 * == CPU suspend finisher ==
41 * =============================
42 *
43 * void omap4_finish_suspend(unsigned long cpu_state)
44 *
45 * This function code saves the CPU context and performs the CPU
46 * power down sequence. Calling WFI effectively changes the CPU
47 * power domains states to the desired target power state.
48 *
49 * @cpu_state : contains context save state (r0)
50 * 0 - No context lost
51 * 1 - CPUx L1 and logic lost: MPUSS CSWR
52 * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
53 * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
54 * @return: This function never returns for CPU OFF and DORMANT power states.
55 * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up
56 * from this follows a full CPU reset path via ROM code to CPU restore code.
57 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
58 * It returns to the caller for CPU INACTIVE and ON power states or in case
59 * CPU failed to transition to targeted OFF/DORMANT state.
60 */
61ENTRY(omap4_finish_suspend)
62 stmfd sp!, {lr}
63 cmp r0, #0x0
64 beq do_WFI @ No lowpower state, jump to WFI
65
66 /*
67 * Flush all data from the L1 data cache before disabling
68 * SCTLR.C bit.
69 */
70 bl omap4_get_sar_ram_base
71 ldr r9, [r0, #OMAP_TYPE_OFFSET]
72 cmp r9, #0x1 @ Check for HS device
73 bne skip_secure_l1_clean
74 mov r0, #SCU_PM_NORMAL
75 mov r1, #0xFF @ clean seucre L1
76 stmfd r13!, {r4-r12, r14}
77 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
78 DO_SMC
79 ldmfd r13!, {r4-r12, r14}
80skip_secure_l1_clean:
81 bl v7_flush_dcache_all
82
83 /*
84 * Clear the SCTLR.C bit to prevent further data cache
85 * allocation. Clearing SCTLR.C would make all the data accesses
86 * strongly ordered and would not hit the cache.
87 */
88 mrc p15, 0, r0, c1, c0, 0
89 bic r0, r0, #(1 << 2) @ Disable the C bit
90 mcr p15, 0, r0, c1, c0, 0
91 isb
92
93 /*
94 * Invalidate L1 data cache. Even though only invalidate is
95 * necessary exported flush API is used here. Doing clean
96 * on already clean cache would be almost NOP.
97 */
98 bl v7_flush_dcache_all
99
100 /*
101 * Switch the CPU from Symmetric Multiprocessing (SMP) mode
102 * to AsymmetricMultiprocessing (AMP) mode by programming
103 * the SCU power status to DORMANT or OFF mode.
104 * This enables the CPU to be taken out of coherency by
105 * preventing the CPU from receiving cache, TLB, or BTB
106 * maintenance operations broadcast by other CPUs in the cluster.
107 */
108 bl omap4_get_sar_ram_base
109 mov r8, r0
110 ldr r9, [r8, #OMAP_TYPE_OFFSET]
111 cmp r9, #0x1 @ Check for HS device
112 bne scu_gp_set
113 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
114 ands r0, r0, #0x0f
115 ldreq r0, [r8, #SCU_OFFSET0]
116 ldrne r0, [r8, #SCU_OFFSET1]
117 mov r1, #0x00
118 stmfd r13!, {r4-r12, r14}
119 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
120 DO_SMC
121 ldmfd r13!, {r4-r12, r14}
122 b skip_scu_gp_set
123scu_gp_set:
124 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
125 ands r0, r0, #0x0f
126 ldreq r1, [r8, #SCU_OFFSET0]
127 ldrne r1, [r8, #SCU_OFFSET1]
128 bl omap4_get_scu_base
129 bl scu_power_mode
130skip_scu_gp_set:
131 mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data
132 tst r0, #(1 << 18)
133 mrcne p15, 0, r0, c1, c0, 1
134 bicne r0, r0, #(1 << 6) @ Disable SMP bit
135 mcrne p15, 0, r0, c1, c0, 1
136 isb
137 dsb
138#ifdef CONFIG_CACHE_L2X0
139 /*
140 * Clean and invalidate the L2 cache.
141 * Common cache-l2x0.c functions can't be used here since it
142 * uses spinlocks. We are out of coherency here with data cache
143 * disabled. The spinlock implementation uses exclusive load/store
144 * instruction which can fail without data cache being enabled.
145 * OMAP4 hardware doesn't support exclusive monitor which can
146 * overcome exclusive access issue. Because of this, CPU can
147 * lead to deadlock.
148 */
149 bl omap4_get_sar_ram_base
150 mov r8, r0
151 mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR
152 ands r5, r5, #0x0f
153 ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR
154 ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory.
155 cmp r0, #3
156 bne do_WFI
157#ifdef CONFIG_PL310_ERRATA_727915
158 mov r0, #0x03
159 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
160 DO_SMC
161#endif
162 bl omap4_get_l2cache_base
163 mov r2, r0
164 ldr r0, =0xffff
165 str r0, [r2, #L2X0_CLEAN_INV_WAY]
166wait:
167 ldr r0, [r2, #L2X0_CLEAN_INV_WAY]
168 ldr r1, =0xffff
169 ands r0, r0, r1
170 bne wait
171#ifdef CONFIG_PL310_ERRATA_727915
172 mov r0, #0x00
173 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
174 DO_SMC
175#endif
176l2x_sync:
177 bl omap4_get_l2cache_base
178 mov r2, r0
179 mov r0, #0x0
180 str r0, [r2, #L2X0_CACHE_SYNC]
181sync:
182 ldr r0, [r2, #L2X0_CACHE_SYNC]
183 ands r0, r0, #0x1
184 bne sync
185#endif
186
187do_WFI:
188 bl omap_do_wfi
189
190 /*
191 * CPU is here when it failed to enter OFF/DORMANT or
192 * no low power state was attempted.
193 */
194 mrc p15, 0, r0, c1, c0, 0
195 tst r0, #(1 << 2) @ Check C bit enabled?
196 orreq r0, r0, #(1 << 2) @ Enable the C bit
197 mcreq p15, 0, r0, c1, c0, 0
198 isb
199
200 /*
201 * Ensure the CPU power state is set to NORMAL in
202 * SCU power state so that CPU is back in coherency.
203 * In non-coherent mode CPU can lock-up and lead to
204 * system deadlock.
205 */
206 mrc p15, 0, r0, c1, c0, 1
207 tst r0, #(1 << 6) @ Check SMP bit enabled?
208 orreq r0, r0, #(1 << 6)
209 mcreq p15, 0, r0, c1, c0, 1
210 isb
211 bl omap4_get_sar_ram_base
212 mov r8, r0
213 ldr r9, [r8, #OMAP_TYPE_OFFSET]
214 cmp r9, #0x1 @ Check for HS device
215 bne scu_gp_clear
216 mov r0, #SCU_PM_NORMAL
217 mov r1, #0x00
218 stmfd r13!, {r4-r12, r14}
219 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
220 DO_SMC
221 ldmfd r13!, {r4-r12, r14}
222 b skip_scu_gp_clear
223scu_gp_clear:
224 bl omap4_get_scu_base
225 mov r1, #SCU_PM_NORMAL
226 bl scu_power_mode
227skip_scu_gp_clear:
228 isb
229 dsb
230 ldmfd sp!, {pc}
231ENDPROC(omap4_finish_suspend)
232
233/*
234 * ============================
235 * == CPU resume entry point ==
236 * ============================
237 *
238 * void omap4_cpu_resume(void)
239 *
240 * ROM code jumps to this function while waking up from CPU
241 * OFF or DORMANT state. Physical address of the function is
242 * stored in the SAR RAM while entering to OFF or DORMANT mode.
243 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
244 */
245ENTRY(omap4_cpu_resume)
246 /*
247 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
248 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
249 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
250 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
251 * OMAP443X GP devices- SMP bit isn't accessible.
252 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
253 */
254 ldr r8, =OMAP44XX_SAR_RAM_BASE
255 ldr r9, [r8, #OMAP_TYPE_OFFSET]
256 cmp r9, #0x1 @ Skip if GP device
257 bne skip_ns_smp_enable
258 mrc p15, 0, r0, c0, c0, 5
259 ands r0, r0, #0x0f
260 beq skip_ns_smp_enable
261ppa_actrl_retry:
262 mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX
263 adr r3, ppa_zero_params @ Pointer to parameters
264 mov r1, #0x0 @ Process ID
265 mov r2, #0x4 @ Flag
266 mov r6, #0xff
267 mov r12, #0x00 @ Secure Service ID
268 DO_SMC
269 cmp r0, #0x0 @ API returns 0 on success.
270 beq enable_smp_bit
271 b ppa_actrl_retry
272enable_smp_bit:
273 mrc p15, 0, r0, c1, c0, 1
274 tst r0, #(1 << 6) @ Check SMP bit enabled?
275 orreq r0, r0, #(1 << 6)
276 mcreq p15, 0, r0, c1, c0, 1
277 isb
278skip_ns_smp_enable:
279#ifdef CONFIG_CACHE_L2X0
280 /*
281 * Restore the L2 AUXCTRL and enable the L2 cache.
282 * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL
283 * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL
284 * register r0 contains value to be programmed.
285 * L2 cache is already invalidate by ROM code as part
286 * of MPUSS OFF wakeup path.
287 */
288 ldr r2, =OMAP44XX_L2CACHE_BASE
289 ldr r0, [r2, #L2X0_CTRL]
290 and r0, #0x0f
291 cmp r0, #1
292 beq skip_l2en @ Skip if already enabled
293 ldr r3, =OMAP44XX_SAR_RAM_BASE
294 ldr r1, [r3, #OMAP_TYPE_OFFSET]
295 cmp r1, #0x1 @ Check for HS device
296 bne set_gp_por
297 ldr r0, =OMAP4_PPA_L2_POR_INDEX
298 ldr r1, =OMAP44XX_SAR_RAM_BASE
299 ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
300 adr r3, ppa_por_params
301 str r4, [r3, #0x04]
302 mov r1, #0x0 @ Process ID
303 mov r2, #0x4 @ Flag
304 mov r6, #0xff
305 mov r12, #0x00 @ Secure Service ID
306 DO_SMC
307 b set_aux_ctrl
308set_gp_por:
309 ldr r1, =OMAP44XX_SAR_RAM_BASE
310 ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
311 ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH
312 DO_SMC
313set_aux_ctrl:
314 ldr r1, =OMAP44XX_SAR_RAM_BASE
315 ldr r0, [r1, #L2X0_AUXCTRL_OFFSET]
316 ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL
317 DO_SMC
318 mov r0, #0x1
319 ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache
320 DO_SMC
321skip_l2en:
322#endif
323
324 b cpu_resume @ Jump to generic resume
325ENDPROC(omap4_cpu_resume)
326#endif
327
328#ifndef CONFIG_OMAP4_ERRATA_I688
329ENTRY(omap_bus_sync)
330 mov pc, lr
331ENDPROC(omap_bus_sync)
332#endif
333
334ENTRY(omap_do_wfi)
335 stmfd sp!, {lr}
336 /* Drain interconnect write buffers. */
337 bl omap_bus_sync
338
339 /*
340 * Execute an ISB instruction to ensure that all of the
341 * CP15 register changes have been committed.
342 */
343 isb
344
345 /*
346 * Execute a barrier instruction to ensure that all cache,
347 * TLB and branch predictor maintenance operations issued
348 * by any CPU in the cluster have completed.
349 */
350 dsb
351 dmb
352
353 /*
354 * Execute a WFI instruction and wait until the
355 * STANDBYWFI output is asserted to indicate that the
356 * CPU is in idle and low power state. CPU can specualatively
357 * prefetch the instructions so add NOPs after WFI. Sixteen
358 * NOPs as per Cortex-A9 pipeline.
359 */
360 wfi @ Wait For Interrupt
361 nop
362 nop
363 nop
364 nop
365 nop
366 nop
367 nop
368 nop
369 nop
370 nop
371 nop
372 nop
373 nop
374 nop
375 nop
376 nop
377
378 ldmfd sp!, {pc}
379ENDPROC(omap_do_wfi)
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 83cca9bcfc97..1bf0df81bdc6 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -131,6 +131,12 @@ extern void imx53_evk_common_init(void);
131extern void imx53_qsb_common_init(void); 131extern void imx53_qsb_common_init(void);
132extern void imx53_smd_common_init(void); 132extern void imx53_smd_common_init(void);
133extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); 133extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
134extern void imx6q_pm_init(void);
135extern void imx6q_clock_map_io(void); 134extern void imx6q_clock_map_io(void);
135
136#ifdef CONFIG_PM
137extern void imx6q_pm_init(void);
138#else
139static inline void imx6q_pm_init(void) {}
140#endif
141
136#endif 142#endif
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index a4d36d601d55..d78298366a91 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -168,7 +168,7 @@ struct cpu_op {
168 u32 cpu_rate; 168 u32 cpu_rate;
169}; 169};
170 170
171int tzic_enable_wake(int is_idle); 171int tzic_enable_wake(void);
172 172
173extern struct cpu_op *(*get_cpu_op)(int *op); 173extern struct cpu_op *(*get_cpu_op)(int *op);
174#endif 174#endif
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index a3c164c7ba82..98308ec1f321 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -73,7 +73,28 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type)
73#define tzic_set_irq_fiq NULL 73#define tzic_set_irq_fiq NULL
74#endif 74#endif
75 75
76static unsigned int *wakeup_intr[4]; 76#ifdef CONFIG_PM
77static void tzic_irq_suspend(struct irq_data *d)
78{
79 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
80 int idx = gc->irq_base >> 5;
81
82 __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx));
83}
84
85static void tzic_irq_resume(struct irq_data *d)
86{
87 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
88 int idx = gc->irq_base >> 5;
89
90 __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)),
91 tzic_base + TZIC_WAKEUP0(idx));
92}
93
94#else
95#define tzic_irq_suspend NULL
96#define tzic_irq_resume NULL
97#endif
77 98
78static struct mxc_extra_irq tzic_extra_irq = { 99static struct mxc_extra_irq tzic_extra_irq = {
79#ifdef CONFIG_FIQ 100#ifdef CONFIG_FIQ
@@ -91,12 +112,13 @@ static __init void tzic_init_gc(unsigned int irq_start)
91 handle_level_irq); 112 handle_level_irq);
92 gc->private = &tzic_extra_irq; 113 gc->private = &tzic_extra_irq;
93 gc->wake_enabled = IRQ_MSK(32); 114 gc->wake_enabled = IRQ_MSK(32);
94 wakeup_intr[idx] = &gc->wake_active;
95 115
96 ct = gc->chip_types; 116 ct = gc->chip_types;
97 ct->chip.irq_mask = irq_gc_mask_disable_reg; 117 ct->chip.irq_mask = irq_gc_mask_disable_reg;
98 ct->chip.irq_unmask = irq_gc_unmask_enable_reg; 118 ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
99 ct->chip.irq_set_wake = irq_gc_set_wake; 119 ct->chip.irq_set_wake = irq_gc_set_wake;
120 ct->chip.irq_suspend = tzic_irq_suspend;
121 ct->chip.irq_resume = tzic_irq_resume;
100 ct->regs.disable = TZIC_ENCLEAR0(idx); 122 ct->regs.disable = TZIC_ENCLEAR0(idx);
101 ct->regs.enable = TZIC_ENSET0(idx); 123 ct->regs.enable = TZIC_ENSET0(idx);
102 124
@@ -167,23 +189,19 @@ void __init tzic_init_irq(void __iomem *irqbase)
167/** 189/**
168 * tzic_enable_wake() - enable wakeup interrupt 190 * tzic_enable_wake() - enable wakeup interrupt
169 * 191 *
170 * @param is_idle 1 if called in idle loop (ENSET0 register);
171 * 0 to be used when called from low power entry
172 * @return 0 if successful; non-zero otherwise 192 * @return 0 if successful; non-zero otherwise
173 */ 193 */
174int tzic_enable_wake(int is_idle) 194int tzic_enable_wake(void)
175{ 195{
176 unsigned int i, v; 196 unsigned int i;
177 197
178 __raw_writel(1, tzic_base + TZIC_DSMINT); 198 __raw_writel(1, tzic_base + TZIC_DSMINT);
179 if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0)) 199 if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
180 return -EAGAIN; 200 return -EAGAIN;
181 201
182 for (i = 0; i < 4; i++) { 202 for (i = 0; i < 4; i++)
183 v = is_idle ? __raw_readl(tzic_base + TZIC_ENSET0(i)) : 203 __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(i)),
184 *wakeup_intr[i]; 204 tzic_base + TZIC_WAKEUP0(i));
185 __raw_writel(v, tzic_base + TZIC_WAKEUP0(i));
186 }
187 205
188 return 0; 206 return 0;
189} 207}
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 2ee6341fffdb..06383b51e655 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -22,6 +22,8 @@
22#include <plat/vram.h> 22#include <plat/vram.h>
23#include <plat/dsp.h> 23#include <plat/dsp.h>
24 24
25#include <plat/omap-secure.h>
26
25 27
26#define NO_LENGTH_CHECK 0xffffffff 28#define NO_LENGTH_CHECK 0xffffffff
27 29
@@ -66,6 +68,7 @@ void __init omap_reserve(void)
66 omapfb_reserve_sdram_memblock(); 68 omapfb_reserve_sdram_memblock();
67 omap_vram_reserve_sdram_memblock(); 69 omap_vram_reserve_sdram_memblock();
68 omap_dsp_reserve_sdram_memblock(); 70 omap_dsp_reserve_sdram_memblock();
71 omap_secure_ram_reserve_memblock();
69} 72}
70 73
71void __init omap_init_consistent_dma_size(void) 74void __init omap_init_consistent_dma_size(void)
diff --git a/arch/arm/plat-omap/include/plat/omap-secure.h b/arch/arm/plat-omap/include/plat/omap-secure.h
new file mode 100644
index 000000000000..64f9d1c7f1bb
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap-secure.h
@@ -0,0 +1,13 @@
1#ifndef __OMAP_SECURE_H__
2#define __OMAP_SECURE_H__
3
4#include <linux/types.h>
5
6#ifdef CONFIG_ARCH_OMAP2PLUS
7extern int omap_secure_ram_reserve_memblock(void);
8#else
9static inline void omap_secure_ram_reserve_memblock(void)
10{ }
11#endif
12
13#endif /* __OMAP_SECURE_H__ */
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 2682043f5a5b..9ff444469f3d 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -19,6 +19,7 @@
19 19
20#include <linux/serial_core.h> 20#include <linux/serial_core.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/pm_qos.h>
22 23
23#include <plat/mux.h> 24#include <plat/mux.h>
24 25
@@ -33,6 +34,8 @@
33 34
34#define OMAP_MODE13X_SPEED 230400 35#define OMAP_MODE13X_SPEED 230400
35 36
37#define OMAP_UART_SCR_TX_EMPTY 0x08
38
36/* WER = 0x7F 39/* WER = 0x7F
37 * Enable module level wakeup in WER reg 40 * Enable module level wakeup in WER reg
38 */ 41 */
@@ -51,18 +54,27 @@
51 54
52#define OMAP_UART_DMA_CH_FREE -1 55#define OMAP_UART_DMA_CH_FREE -1
53 56
54#define RX_TIMEOUT (3 * HZ)
55#define OMAP_MAX_HSUART_PORTS 4 57#define OMAP_MAX_HSUART_PORTS 4
56 58
57#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA 59#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
58 60
61#define UART_ERRATA_i202_MDR1_ACCESS BIT(0)
62#define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1)
63
59struct omap_uart_port_info { 64struct omap_uart_port_info {
60 bool dma_enabled; /* To specify DMA Mode */ 65 bool dma_enabled; /* To specify DMA Mode */
61 unsigned int uartclk; /* UART clock rate */ 66 unsigned int uartclk; /* UART clock rate */
62 void __iomem *membase; /* ioremap cookie or NULL */
63 resource_size_t mapbase; /* resource base */
64 unsigned long irqflags; /* request_irq flags */
65 upf_t flags; /* UPF_* flags */ 67 upf_t flags; /* UPF_* flags */
68 u32 errata;
69 unsigned int dma_rx_buf_size;
70 unsigned int dma_rx_timeout;
71 unsigned int autosuspend_timeout;
72 unsigned int dma_rx_poll_rate;
73
74 int (*get_context_loss_count)(struct device *);
75 void (*set_forceidle)(struct platform_device *);
76 void (*set_noidle)(struct platform_device *);
77 void (*enable_wakeup)(struct platform_device *, bool);
66}; 78};
67 79
68struct uart_omap_dma { 80struct uart_omap_dma {
@@ -86,8 +98,9 @@ struct uart_omap_dma {
86 spinlock_t rx_lock; 98 spinlock_t rx_lock;
87 /* timer to poll activity on rx dma */ 99 /* timer to poll activity on rx dma */
88 struct timer_list rx_timer; 100 struct timer_list rx_timer;
89 int rx_buf_size; 101 unsigned int rx_buf_size;
90 int rx_timeout; 102 unsigned int rx_poll_rate;
103 unsigned int rx_timeout;
91}; 104};
92 105
93struct uart_omap_port { 106struct uart_omap_port {
@@ -100,6 +113,10 @@ struct uart_omap_port {
100 unsigned char mcr; 113 unsigned char mcr;
101 unsigned char fcr; 114 unsigned char fcr;
102 unsigned char efr; 115 unsigned char efr;
116 unsigned char dll;
117 unsigned char dlh;
118 unsigned char mdr1;
119 unsigned char scr;
103 120
104 int use_dma; 121 int use_dma;
105 /* 122 /*
@@ -111,6 +128,14 @@ struct uart_omap_port {
111 unsigned char msr_saved_flags; 128 unsigned char msr_saved_flags;
112 char name[20]; 129 char name[20];
113 unsigned long port_activity; 130 unsigned long port_activity;
131 u32 context_loss_cnt;
132 u32 errata;
133 u8 wakeups_enabled;
134
135 struct pm_qos_request pm_qos_request;
136 u32 latency;
137 u32 calc_latency;
138 struct work_struct qos_work;
114}; 139};
115 140
116#endif /* __OMAP_SERIAL_H__ */ 141#endif /* __OMAP_SERIAL_H__ */
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index ea2b8a6306e7..c0d478e55c84 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -45,6 +45,7 @@
45#define OMAP44XX_WKUPGEN_BASE 0x48281000 45#define OMAP44XX_WKUPGEN_BASE 0x48281000
46#define OMAP44XX_MCPDM_BASE 0x40132000 46#define OMAP44XX_MCPDM_BASE 0x40132000
47#define OMAP44XX_MCPDM_L3_BASE 0x49032000 47#define OMAP44XX_MCPDM_L3_BASE 0x49032000
48#define OMAP44XX_SAR_RAM_BASE 0x4a326000
48 49
49#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000) 50#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)
50#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000) 51#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 8b372ede17c1..647010109afa 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -97,6 +97,7 @@ struct omap_hwmod_mux_info {
97 struct omap_device_pad *pads; 97 struct omap_device_pad *pads;
98 int nr_pads_dynamic; 98 int nr_pads_dynamic;
99 struct omap_device_pad **pads_dynamic; 99 struct omap_device_pad **pads_dynamic;
100 int *irqs;
100 bool enabled; 101 bool enabled;
101}; 102};
102 103
@@ -416,10 +417,13 @@ struct omap_hwmod_omap4_prcm {
416 * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module 417 * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
417 * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP 418 * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
418 * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached 419 * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
420 * _HWMOD_SKIP_ENABLE: set if hwmod enabled during init (HWMOD_INIT_NO_IDLE) -
421 * causes the first call to _enable() to only update the pinmux
419 */ 422 */
420#define _HWMOD_NO_MPU_PORT (1 << 0) 423#define _HWMOD_NO_MPU_PORT (1 << 0)
421#define _HWMOD_WAKEUP_ENABLED (1 << 1) 424#define _HWMOD_WAKEUP_ENABLED (1 << 1)
422#define _HWMOD_SYSCONFIG_LOADED (1 << 2) 425#define _HWMOD_SYSCONFIG_LOADED (1 << 2)
426#define _HWMOD_SKIP_ENABLE (1 << 3)
423 427
424/* 428/*
425 * omap_hwmod._state definitions 429 * omap_hwmod._state definitions
@@ -604,6 +608,8 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
604 608
605int omap_hwmod_no_setup_reset(struct omap_hwmod *oh); 609int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
606 610
611int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx);
612
607/* 613/*
608 * Chip variant-specific hwmod init routines - XXX should be converted 614 * Chip variant-specific hwmod init routines - XXX should be converted
609 * to use initcalls once the initial boot ordering is straightened out 615 * to use initcalls once the initial boot ordering is straightened out
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index 80b6d39c31ec..198d1e6a4a6c 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -107,15 +107,13 @@
107#ifndef __ASSEMBLER__ 107#ifndef __ASSEMBLER__
108 108
109struct omap_board_data; 109struct omap_board_data;
110struct omap_uart_port_info;
110 111
111extern void omap_serial_init(void); 112extern void omap_serial_init(void);
112extern void omap_serial_init_port(struct omap_board_data *bdata);
113extern int omap_uart_can_sleep(void); 113extern int omap_uart_can_sleep(void);
114extern void omap_uart_check_wakeup(void); 114extern void omap_serial_board_init(struct omap_uart_port_info *platform_data);
115extern void omap_uart_prepare_suspend(void); 115extern void omap_serial_init_port(struct omap_board_data *bdata,
116extern void omap_uart_prepare_idle(int num); 116 struct omap_uart_port_info *platform_data);
117extern void omap_uart_resume_idle(int num);
118extern void omap_uart_enable_irqs(int enable);
119#endif 117#endif
120 118
121#endif 119#endif
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index f500fc34d065..75aa1b2bef51 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -95,6 +95,10 @@ static inline void omap_push_sram_idle(void) {}
95 */ 95 */
96#define OMAP2_SRAM_PA 0x40200000 96#define OMAP2_SRAM_PA 0x40200000
97#define OMAP3_SRAM_PA 0x40200000 97#define OMAP3_SRAM_PA 0x40200000
98#ifdef CONFIG_OMAP4_ERRATA_I688
99#define OMAP4_SRAM_PA 0x40304000
100#define OMAP4_SRAM_VA 0xfe404000
101#else
98#define OMAP4_SRAM_PA 0x40300000 102#define OMAP4_SRAM_PA 0x40300000
99 103#endif
100#endif 104#endif
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 6b058a621e8d..4243bdcc87bc 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -40,7 +40,11 @@
40#define OMAP1_SRAM_PA 0x20000000 40#define OMAP1_SRAM_PA 0x20000000
41#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) 41#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800)
42#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) 42#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000)
43#ifdef CONFIG_OMAP4_ERRATA_I688
44#define OMAP4_SRAM_PUB_PA OMAP4_SRAM_PA
45#else
43#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) 46#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000)
47#endif
44 48
45#if defined(CONFIG_ARCH_OMAP2PLUS) 49#if defined(CONFIG_ARCH_OMAP2PLUS)
46#define SRAM_BOOTLOADER_SZ 0x00 50#define SRAM_BOOTLOADER_SZ 0x00
@@ -161,6 +165,10 @@ static void __init omap_map_sram(void)
161 if (omap_sram_size == 0) 165 if (omap_sram_size == 0)
162 return; 166 return;
163 167
168#ifdef CONFIG_OMAP4_ERRATA_I688
169 omap_sram_start += PAGE_SIZE;
170 omap_sram_size -= SZ_16K;
171#endif
164 if (cpu_is_omap34xx()) { 172 if (cpu_is_omap34xx()) {
165 /* 173 /*
166 * SRAM must be marked as non-cached on OMAP3 since the 174 * SRAM must be marked as non-cached on OMAP3 since the