commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=ab1962d4fe13fd81b5fe70adcc911e182f0f1f1c branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/2012R1
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 <[email protected]> --- arch/blackfin/include/asm/gpio.h | 2 + arch/blackfin/include/asm/irq.h | 10 ++++ arch/blackfin/mach-bf609/pm.c | 9 ++- arch/blackfin/mach-common/ints-priority.c | 72 +++++++++++++++++++++------- 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 12d3571..18a86c4 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h @@ -140,6 +140,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 12f4060..e2a0d2a 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 5a1748e..0a4c055 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 88fa12c..ac64377 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -403,24 +403,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 @@ -1101,6 +1083,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; @@ -1136,6 +1121,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 ca6655e..4878f36 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();
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
