aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Miao <realmz6@gmail.com>2012-06-14 06:04:01 -0400
committerBob Liu <lliubbo@gmail.com>2012-07-24 01:39:51 -0400
commitd49cdf84096392359a4d532733ab5a165d24bb0d (patch)
tree6fcf9be93ab88c1424184cd9e76f594a4e1cf9ec
parent688da5e87aeb5094450f941d5a755ce04e25f4a1 (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>
-rw-r--r--arch/blackfin/include/asm/gpio.h2
-rw-r--r--arch/blackfin/include/asm/irq.h10
-rw-r--r--arch/blackfin/mach-bf609/pm.c9
-rw-r--r--arch/blackfin/mach-common/ints-priority.c72
-rw-r--r--arch/blackfin/mach-common/pm.c4
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
142void bfin_gpio_pm_hibernate_restore(void); 142void bfin_gpio_pm_hibernate_restore(void);
143void bfin_gpio_pm_hibernate_suspend(void); 143void bfin_gpio_pm_hibernate_suspend(void);
144void bfin_pint_suspend(void);
145void bfin_pint_resume(void);
144 146
145# if !BFIN_GPIO_PINT 147# if !BFIN_GPIO_PINT
146int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl); 148int 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 */
26struct 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
399static int sec_suspend(void)
400{
401 return 0;
402}
403
404static 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
412static 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
1078static struct bfin_pm_pint_save save_pint_reg[NR_PINT_SYS_IRQS];
1079static u32 save_pint_sec_ctl[NR_PINT_SYS_IRQS];
1080
1096static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) 1081static 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
1117void 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
1129void 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
1141static 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
1150static 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
1163static 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