diff options
| author | Anson Huang <b20788@freescale.com> | 2012-03-23 14:08:51 +0800 |
|---|---|---|
| committer | Eric Nelson <eric.nelson@boundarydevices.com> | 2012-08-28 09:44:37 -0700 |
| commit | c1fcb3a0f8e698d2a09794dfec7c3fe40261fc9a (patch) | |
| tree | 9d4f8b06709127c3837bb52d58aa4da2eb3c5c59 | |
| parent | d43396568c49b2985071401e947e8d4871c9793f (diff) | |
ENGR00177757 Fix suspend/resume issue when enable localtimer
Need to disable localtimer's PPI when suspend, or ARM core
will run into exception when resume.
Signed-off-by: Anson Huang <b20788@freescale.com>
| -rw-r--r-- | arch/arm/common/gic.c | 9 | ||||
| -rw-r--r-- | arch/arm/include/asm/hardware/gic.h | 1 | ||||
| -rw-r--r-- | arch/arm/kernel/smp_twd.c | 3 |
3 files changed, 13 insertions, 0 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index ab8c07d48a26..b33a75f1acef 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -385,6 +385,15 @@ void __cpuinit gic_enable_ppi(unsigned int irq) gic_unmask_irq(irq_get_irq_data(irq)); local_irq_restore(flags); } +void __cpuinit gic_disable_ppi(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + irq_set_status_flags(irq, IRQ_NOPROBE); + gic_mask_irq(irq_get_irq_data(irq)); + local_irq_restore(flags); +} void save_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs) { diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 0fa541d200bb..c8647b309ab1 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -67,6 +67,7 @@ void gic_secondary_init(unsigned int); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); void gic_enable_ppi(unsigned int); +void gic_disable_ppi(unsigned int); void save_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs); void restore_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs); void save_gic_dist_state(unsigned int gic_nr, struct gic_dist_state *gds); diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 983f8cc078cb..a5a2f45069d5 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -43,15 +43,18 @@ static void twd_set_mode(enum clock_event_mode mode, ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_PERIODIC; __raw_writel(twd_timer_rate / HZ, twd_base + TWD_TIMER_LOAD); + gic_enable_ppi(clk->irq); break; case CLOCK_EVT_MODE_ONESHOT: /* period set, and timer enabled in 'next_event' hook */ ctrl = TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_ONESHOT; + gic_enable_ppi(clk->irq); break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: default: ctrl = 0; + gic_disable_ppi(clk->irq); } __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL); |
