diff options
author | Steven Miao <realmz6@gmail.com> | 2012-06-14 18:04:01 +0800 |
---|---|---|
committer | Bob Liu <lliubbo@gmail.com> | 2012-07-24 13:39:51 +0800 |
commit | d49cdf84096392359a4d532733ab5a165d24bb0d (patch) | |
tree | 6fcf9be93ab88c1424184cd9e76f594a4e1cf9ec /arch/blackfin/mach-common/ints-priority.c | |
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/mach-common/ints-priority.c')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 72 |
1 files changed, 54 insertions, 18 deletions
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 |