diff options
author | Steven Miao <realmz6@gmail.com> | 2012-06-14 06:04:01 -0400 |
---|---|---|
committer | Bob Liu <lliubbo@gmail.com> | 2012-07-24 01:39:51 -0400 |
commit | d49cdf84096392359a4d532733ab5a165d24bb0d (patch) | |
tree | 6fcf9be93ab88c1424184cd9e76f594a4e1cf9ec /arch/blackfin | |
parent | 688da5e87aeb5094450f941d5a755ce04e25f4a1 (diff) |
bf60x: pm: add pint suspend and resume support
save and restore pint sec CTL
save and restore pint registers
add pint suspend and resume when suspend to mem
Signed-off-by: Steven Miao <realmz6@gmail.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/include/asm/gpio.h | 2 | ||||
-rw-r--r-- | arch/blackfin/include/asm/irq.h | 10 | ||||
-rw-r--r-- | arch/blackfin/mach-bf609/pm.c | 9 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 72 | ||||
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 4 |
5 files changed, 76 insertions, 21 deletions
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 3d84d96f7c2c..98d0133346b5 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h | |||
@@ -141,6 +141,8 @@ static inline void bfin_pm_standby_restore(void) | |||
141 | 141 | ||
142 | void bfin_gpio_pm_hibernate_restore(void); | 142 | void bfin_gpio_pm_hibernate_restore(void); |
143 | void bfin_gpio_pm_hibernate_suspend(void); | 143 | void bfin_gpio_pm_hibernate_suspend(void); |
144 | void bfin_pint_suspend(void); | ||
145 | void bfin_pint_resume(void); | ||
144 | 146 | ||
145 | # if !BFIN_GPIO_PINT | 147 | # if !BFIN_GPIO_PINT |
146 | int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl); | 148 | int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl); |
diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h index 89de539ed010..4ae1144a4578 100644 --- a/arch/blackfin/include/asm/irq.h +++ b/arch/blackfin/include/asm/irq.h | |||
@@ -20,6 +20,16 @@ | |||
20 | /* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */ | 20 | /* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */ |
21 | #include <mach/irq.h> | 21 | #include <mach/irq.h> |
22 | 22 | ||
23 | /* | ||
24 | * pm save bfin pint registers | ||
25 | */ | ||
26 | struct bfin_pm_pint_save { | ||
27 | u32 mask_set; | ||
28 | u32 assign; | ||
29 | u32 edge_set; | ||
30 | u32 invert_set; | ||
31 | }; | ||
32 | |||
23 | #if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE) | 33 | #if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE) |
24 | # define NOP_PAD_ANOMALY_05000244 "nop; nop;" | 34 | # define NOP_PAD_ANOMALY_05000244 "nop; nop;" |
25 | #else | 35 | #else |
diff --git a/arch/blackfin/mach-bf609/pm.c b/arch/blackfin/mach-bf609/pm.c index 8d815e057100..0211ebd142c4 100644 --- a/arch/blackfin/mach-bf609/pm.c +++ b/arch/blackfin/mach-bf609/pm.c | |||
@@ -342,16 +342,19 @@ static int __init bf609_init_pm(void) | |||
342 | GPIO_PE12, error); | 342 | GPIO_PE12, error); |
343 | } | 343 | } |
344 | 344 | ||
345 | error = request_irq(irq, test_isr, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, "gpiope12", NULL); | 345 | error = request_irq(irq, test_isr, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND |
346 | | IRQF_FORCE_RESUME, "gpiope12", NULL); | ||
346 | if(error < 0) | 347 | if(error < 0) |
347 | printk(KERN_DEBUG "Unable to get irq\n"); | 348 | printk(KERN_DEBUG "Unable to get irq\n"); |
348 | #endif | 349 | #endif |
349 | 350 | ||
350 | error = request_irq(IRQ_CGU_EVT, dpm0_isr, IRQF_NO_SUSPEND, "cgu0 event", NULL); | 351 | error = request_irq(IRQ_CGU_EVT, dpm0_isr, IRQF_NO_SUSPEND | |
352 | IRQF_FORCE_RESUME, "cgu0 event", NULL); | ||
351 | if(error < 0) | 353 | if(error < 0) |
352 | printk(KERN_DEBUG "Unable to get irq\n"); | 354 | printk(KERN_DEBUG "Unable to get irq\n"); |
353 | 355 | ||
354 | error = request_irq(IRQ_DPM, dpm0_isr, IRQF_NO_SUSPEND, "dpm0 event", NULL); | 356 | error = request_irq(IRQ_DPM, dpm0_isr, IRQF_NO_SUSPEND | |
357 | IRQF_FORCE_RESUME, "dpm0 event", NULL); | ||
355 | if (error < 0) | 358 | if (error < 0) |
356 | printk(KERN_DEBUG "Unable to get irq\n"); | 359 | printk(KERN_DEBUG "Unable to get irq\n"); |
357 | 360 | ||
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 9c7d65aee275..1aac5ebaace4 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -396,24 +396,6 @@ void handle_sec_fault(unsigned int irq, struct irq_desc *desc) | |||
396 | raw_spin_unlock(&desc->lock); | 396 | raw_spin_unlock(&desc->lock); |
397 | } | 397 | } |
398 | 398 | ||
399 | static int sec_suspend(void) | ||
400 | { | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static void sec_resume(void) | ||
405 | { | ||
406 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); | ||
407 | udelay(100); | ||
408 | bfin_write_SEC_GCTL(SEC_GCTL_EN); | ||
409 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); | ||
410 | } | ||
411 | |||
412 | static struct syscore_ops sec_pm_syscore_ops = { | ||
413 | .suspend = sec_suspend, | ||
414 | .resume = sec_resume, | ||
415 | }; | ||
416 | |||
417 | #endif | 399 | #endif |
418 | 400 | ||
419 | #ifdef CONFIG_SMP | 401 | #ifdef CONFIG_SMP |
@@ -1093,6 +1075,9 @@ static int bfin_gpio_irq_type(struct irq_data *d, unsigned int type) | |||
1093 | } | 1075 | } |
1094 | 1076 | ||
1095 | #ifdef CONFIG_PM | 1077 | #ifdef CONFIG_PM |
1078 | static struct bfin_pm_pint_save save_pint_reg[NR_PINT_SYS_IRQS]; | ||
1079 | static u32 save_pint_sec_ctl[NR_PINT_SYS_IRQS]; | ||
1080 | |||
1096 | static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) | 1081 | static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) |
1097 | { | 1082 | { |
1098 | u32 pint_irq; | 1083 | u32 pint_irq; |
@@ -1128,6 +1113,57 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) | |||
1128 | 1113 | ||
1129 | return 0; | 1114 | return 0; |
1130 | } | 1115 | } |
1116 | |||
1117 | void bfin_pint_suspend(void) | ||
1118 | { | ||
1119 | u32 bank; | ||
1120 | |||
1121 | for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { | ||
1122 | save_pint_reg[bank].mask_set = pint[bank]->mask_set; | ||
1123 | save_pint_reg[bank].assign = pint[bank]->assign; | ||
1124 | save_pint_reg[bank].edge_set = pint[bank]->edge_set; | ||
1125 | save_pint_reg[bank].invert_set = pint[bank]->invert_set; | ||
1126 | } | ||
1127 | } | ||
1128 | |||
1129 | void bfin_pint_resume(void) | ||
1130 | { | ||
1131 | u32 bank; | ||
1132 | |||
1133 | for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { | ||
1134 | pint[bank]->mask_set = save_pint_reg[bank].mask_set; | ||
1135 | pint[bank]->assign = save_pint_reg[bank].assign; | ||
1136 | pint[bank]->edge_set = save_pint_reg[bank].edge_set; | ||
1137 | pint[bank]->invert_set = save_pint_reg[bank].invert_set; | ||
1138 | } | ||
1139 | } | ||
1140 | |||
1141 | static int sec_suspend(void) | ||
1142 | { | ||
1143 | u32 bank; | ||
1144 | |||
1145 | for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) | ||
1146 | save_pint_sec_ctl[bank] = bfin_read_SEC_SCTL(bank + SIC_SYSIRQ(IRQ_PINT0)); | ||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | static void sec_resume(void) | ||
1151 | { | ||
1152 | u32 bank; | ||
1153 | |||
1154 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); | ||
1155 | udelay(100); | ||
1156 | bfin_write_SEC_GCTL(SEC_GCTL_EN); | ||
1157 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); | ||
1158 | |||
1159 | for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) | ||
1160 | bfin_write_SEC_SCTL(bank + SIC_SYSIRQ(IRQ_PINT0), save_pint_sec_ctl[bank]); | ||
1161 | } | ||
1162 | |||
1163 | static struct syscore_ops sec_pm_syscore_ops = { | ||
1164 | .suspend = sec_suspend, | ||
1165 | .resume = sec_resume, | ||
1166 | }; | ||
1131 | #else | 1167 | #else |
1132 | # define bfin_gpio_set_wake NULL | 1168 | # define bfin_gpio_set_wake NULL |
1133 | #endif | 1169 | #endif |
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index ca6655e0d653..4878f36066c5 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -172,6 +172,8 @@ int bfin_pm_suspend_mem_enter(void) | |||
172 | 172 | ||
173 | bfin_gpio_pm_hibernate_suspend(); | 173 | bfin_gpio_pm_hibernate_suspend(); |
174 | 174 | ||
175 | bfin_pint_suspend(); | ||
176 | |||
175 | #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) | 177 | #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) |
176 | flushinv_all_dcache(); | 178 | flushinv_all_dcache(); |
177 | #endif | 179 | #endif |
@@ -190,6 +192,8 @@ int bfin_pm_suspend_mem_enter(void) | |||
190 | _enable_icplb(); | 192 | _enable_icplb(); |
191 | _enable_dcplb(); | 193 | _enable_dcplb(); |
192 | 194 | ||
195 | bfin_pint_resume(); | ||
196 | |||
193 | bfin_gpio_pm_hibernate_restore(); | 197 | bfin_gpio_pm_hibernate_restore(); |
194 | blackfin_dma_resume(); | 198 | blackfin_dma_resume(); |
195 | 199 | ||