diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-01-03 15:27:56 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-01-03 15:27:56 -0500 |
commit | 038485ea9b66858c17f82e5393004532825106a7 (patch) | |
tree | e411be1686e4ed73c4f74f0388410231d26e5c76 /arch/arm | |
parent | 5d3cb0ffdd0c8987dc17a2ef4529b246198ceb72 (diff) | |
parent | 8b69791215857e3e885d27b3945759ace820794a (diff) |
Merge branch 'imx6/pm' into next/pm
* imx6/pm:
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
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-imx/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-imx/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/mach-imx/head-v7.S | 15 | ||||
-rw-r--r-- | arch/arm/mach-imx/pm-imx6q.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx5/mm.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-mx5/system.c | 3 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/common.h | 8 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/mxc.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-mxc/tzic.c | 40 |
9 files changed, 74 insertions, 22 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index c44aa974e79c..0929768573ba 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -595,6 +595,7 @@ comment "i.MX6 family:" | |||
595 | 595 | ||
596 | config SOC_IMX6Q | 596 | config SOC_IMX6Q |
597 | bool "i.MX6 Quad support" | 597 | bool "i.MX6 Quad support" |
598 | select ARM_CPU_SUSPEND if PM | ||
598 | select ARM_GIC | 599 | select ARM_GIC |
599 | select CACHE_L2X0 | 600 | select CACHE_L2X0 |
600 | select CPU_V7 | 601 | select CPU_V7 |
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index aba73214c2a8..7a739bb5915e 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 | |||
70 | obj-$(CONFIG_SMP) += platsmp.o | 70 | obj-$(CONFIG_SMP) += platsmp.o |
71 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 71 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
72 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | 72 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o |
73 | obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o pm-imx6q.o | 73 | obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o |
74 | |||
75 | ifeq ($(CONFIG_PM),y) | ||
76 | obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o | ||
77 | endif | ||
diff --git a/arch/arm/mach-imx/head-v7.S b/arch/arm/mach-imx/head-v7.S index 6229efbc70cb..cec23a857c7e 100644 --- a/arch/arm/mach-imx/head-v7.S +++ b/arch/arm/mach-imx/head-v7.S | |||
@@ -71,6 +71,7 @@ ENTRY(v7_secondary_startup) | |||
71 | ENDPROC(v7_secondary_startup) | 71 | ENDPROC(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 | ||
94 | phys_l2x0_saved_regs: | ||
95 | .long 0 | ||
96 | #else | ||
97 | .macro pl310_resume | ||
98 | .endm | ||
99 | #endif | ||
100 | |||
91 | ENTRY(v7_cpu_resume) | 101 | ENTRY(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 |
95 | ENDPROC(v7_cpu_resume) | 105 | ENDPROC(v7_cpu_resume) |
96 | 106 | #endif | |
97 | .globl phys_l2x0_saved_regs | ||
98 | phys_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 | ||
25 | static struct clk *gpc_dvfs_clk; | ||
26 | |||
24 | static void imx5_idle(void) | 27 | static 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(); | ||
41 | err1: | ||
42 | clk_disable(gpc_dvfs_clk); | ||
43 | } | ||
44 | err0: | ||
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/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 6698cae942f7..3846c53f5b5d 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h | |||
@@ -130,6 +130,12 @@ extern void imx53_evk_common_init(void); | |||
130 | extern void imx53_qsb_common_init(void); | 130 | extern void imx53_qsb_common_init(void); |
131 | extern void imx53_smd_common_init(void); | 131 | extern void imx53_smd_common_init(void); |
132 | extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); | 132 | extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); |
133 | extern void imx6q_pm_init(void); | ||
134 | extern void imx6q_clock_map_io(void); | 133 | extern void imx6q_clock_map_io(void); |
134 | |||
135 | #ifdef CONFIG_PM | ||
136 | extern void imx6q_pm_init(void); | ||
137 | #else | ||
138 | static inline void imx6q_pm_init(void) {} | ||
139 | #endif | ||
140 | |||
135 | #endif | 141 | #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 | ||
171 | int tzic_enable_wake(int is_idle); | 171 | int tzic_enable_wake(void); |
172 | 172 | ||
173 | extern struct cpu_op *(*get_cpu_op)(int *op); | 173 | extern 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 | ||
76 | static unsigned int *wakeup_intr[4]; | 76 | #ifdef CONFIG_PM |
77 | static 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 | |||
85 | static 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 | ||
78 | static struct mxc_extra_irq tzic_extra_irq = { | 99 | static 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 | */ |
174 | int tzic_enable_wake(int is_idle) | 194 | int 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 | } |