summary refs log tree commit diff
diff options
context:
space:
mode:
authorSteven Miao <realmz6@gmail.com>2012-06-14 18:04:01 +0800
committerBob Liu <lliubbo@gmail.com>2012-07-24 13:39:51 +0800
commitd49cdf84096392359a4d532733ab5a165d24bb0d (patch)
tree6fcf9be93ab88c1424184cd9e76f594a4e1cf9ec
parent688da5e87aeb5094450f941d5a755ce04e25f4a1 (diff)
downloadlinux-d49cdf84096392359a4d532733ab5a165d24bb0d.tar.gz
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)
 
 void bfin_gpio_pm_hibernate_restore(void);
 void bfin_gpio_pm_hibernate_suspend(void);
+void bfin_pint_suspend(void);
+void bfin_pint_resume(void);
 
 # if !BFIN_GPIO_PINT
 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 @@
 /* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */
 #include <mach/irq.h>
 
+/*
+ * pm save bfin pint registers
+ */
+struct bfin_pm_pint_save {
+	u32 mask_set;
+	u32 assign;
+	u32 edge_set;
+	u32 invert_set;
+};
+
 #if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE)
 # define NOP_PAD_ANOMALY_05000244 "nop; nop;"
 #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)
 				GPIO_PE12, error);
 	}
 
-	error = request_irq(irq, test_isr, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, "gpiope12", NULL);
+	error = request_irq(irq, test_isr, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND
+				| IRQF_FORCE_RESUME, "gpiope12", NULL);
 	if(error < 0)
 		printk(KERN_DEBUG "Unable to get irq\n");
 #endif
 
-	error = request_irq(IRQ_CGU_EVT, dpm0_isr, IRQF_NO_SUSPEND, "cgu0 event", NULL);
+	error = request_irq(IRQ_CGU_EVT, dpm0_isr, IRQF_NO_SUSPEND |
+				IRQF_FORCE_RESUME, "cgu0 event", NULL);
 	if(error < 0)
 		printk(KERN_DEBUG "Unable to get irq\n");
 
-	error = request_irq(IRQ_DPM, dpm0_isr, IRQF_NO_SUSPEND, "dpm0 event", NULL);
+	error = request_irq(IRQ_DPM, dpm0_isr, IRQF_NO_SUSPEND |
+				IRQF_FORCE_RESUME, "dpm0 event", NULL);
 	if (error < 0)
 		printk(KERN_DEBUG "Unable to get irq\n");
 
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)
 	raw_spin_unlock(&desc->lock);
 }
 
-static int sec_suspend(void)
-{
-	return 0;
-}
-
-static void sec_resume(void)
-{
-	bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET);
-	udelay(100);
-	bfin_write_SEC_GCTL(SEC_GCTL_EN);
-	bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN);
-}
-
-static struct syscore_ops sec_pm_syscore_ops = {
-	.suspend = sec_suspend,
-	.resume = sec_resume,
-};
-
 #endif
 
 #ifdef CONFIG_SMP
@@ -1093,6 +1075,9 @@ static int bfin_gpio_irq_type(struct irq_data *d, unsigned int type)
 }
 
 #ifdef CONFIG_PM
+static struct bfin_pm_pint_save save_pint_reg[NR_PINT_SYS_IRQS];
+static u32 save_pint_sec_ctl[NR_PINT_SYS_IRQS];
+
 static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
 {
 	u32 pint_irq;
@@ -1128,6 +1113,57 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
 
 	return 0;
 }
+
+void bfin_pint_suspend(void)
+{
+	u32 bank;
+
+	for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) {
+		save_pint_reg[bank].mask_set = pint[bank]->mask_set;
+		save_pint_reg[bank].assign = pint[bank]->assign;
+		save_pint_reg[bank].edge_set = pint[bank]->edge_set;
+		save_pint_reg[bank].invert_set = pint[bank]->invert_set;
+	}
+}
+
+void bfin_pint_resume(void)
+{
+	u32 bank;
+
+	for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) {
+		pint[bank]->mask_set = save_pint_reg[bank].mask_set;
+		pint[bank]->assign = save_pint_reg[bank].assign;
+		pint[bank]->edge_set = save_pint_reg[bank].edge_set;
+		pint[bank]->invert_set = save_pint_reg[bank].invert_set;
+	}
+}
+
+static int sec_suspend(void)
+{
+	u32 bank;
+
+	for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++)
+		save_pint_sec_ctl[bank] = bfin_read_SEC_SCTL(bank + SIC_SYSIRQ(IRQ_PINT0));
+	return 0;
+}
+
+static void sec_resume(void)
+{
+	u32 bank;
+
+	bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET);
+	udelay(100);
+	bfin_write_SEC_GCTL(SEC_GCTL_EN);
+	bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN);
+
+	for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++)
+		bfin_write_SEC_SCTL(bank + SIC_SYSIRQ(IRQ_PINT0), save_pint_sec_ctl[bank]);
+}
+
+static struct syscore_ops sec_pm_syscore_ops = {
+	.suspend = sec_suspend,
+	.resume = sec_resume,
+};
 #else
 # define bfin_gpio_set_wake NULL
 #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)
 
 	bfin_gpio_pm_hibernate_suspend();
 
+	bfin_pint_suspend();
+
 #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
 	flushinv_all_dcache();
 #endif
@@ -190,6 +192,8 @@ int bfin_pm_suspend_mem_enter(void)
 	_enable_icplb();
 	_enable_dcplb();
 
+	bfin_pint_resume();
+
 	bfin_gpio_pm_hibernate_restore();
 	blackfin_dma_resume();