diff options
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/irq.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-pxa/lubbock.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/mainstone.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/time.c | 58 |
4 files changed, 63 insertions, 11 deletions
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index f3cac43124a5..539b596005fc 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -133,7 +133,7 @@ static struct irqchip pxa_low_gpio_chip = { .ack = pxa_ack_low_gpio, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, - .type = pxa_gpio_irq_type, + .set_type = pxa_gpio_irq_type, }; /* @@ -157,7 +157,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, mask >>= 2; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -172,7 +172,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, desc = irq_desc + irq; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -187,7 +187,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, desc = irq_desc + irq; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -203,7 +203,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, desc = irq_desc + irq; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -241,7 +241,7 @@ static struct irqchip pxa_muxed_gpio_chip = { .ack = pxa_ack_muxed_gpio, .mask = pxa_mask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio, - .type = pxa_gpio_irq_type, + .set_type = pxa_gpio_irq_type, }; diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 6309853b59be..923f6eb774c0 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -84,7 +84,7 @@ static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, if (likely(pending)) { irq = LUBBOCK_IRQ(0) + __ffs(pending); desc = irq_desc + irq; - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); } pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; } while (pending); diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 827b7b5a5be8..85fdb5b1470a 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -72,7 +72,7 @@ static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc, if (likely(pending)) { irq = MAINSTONE_IRQ(0) + __ffs(pending); desc = irq_desc + irq; - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); } pending = MST_INTSETCLR & mainstone_irq_enabled; } while (pending); diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 6e5202154f91..7dad3f1465e0 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -70,6 +70,11 @@ static unsigned long pxa_gettimeoffset (void) return usec; } +#ifdef CONFIG_NO_IDLE_HZ +static unsigned long initial_match; +static int match_posponed; +#endif + static irqreturn_t pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -77,11 +82,19 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) write_seqlock(&xtime_lock); +#ifdef CONFIG_NO_IDLE_HZ + if (match_posponed) { + match_posponed = 0; + OSMR0 = initial_match; + } +#endif + /* Loop until we get ahead of the free running timer. * This ensures an exact clock tick count and time accuracy. - * IRQs are disabled inside the loop to ensure coherence between - * lost_ticks (updated in do_timer()) and the match reg value, so we - * can use do_gettimeofday() from interrupt handlers. + * Since IRQs are disabled at this point, coherence between + * lost_ticks(updated in do_timer()) and the match reg value is + * ensured, hence we can use do_gettimeofday() from interrupt + * handlers. * * HACK ALERT: it seems that the PXA timer regs aren't updated right * away in all cases when a write occurs. We therefore compare with @@ -126,6 +139,42 @@ static void __init pxa_timer_init(void) OSCR = 0; /* initialize free-running timer, force first match */ } +#ifdef CONFIG_NO_IDLE_HZ +static int pxa_dyn_tick_enable_disable(void) +{ + /* nothing to do */ + return 0; +} + +static void pxa_dyn_tick_reprogram(unsigned long ticks) +{ + if (ticks > 1) { + initial_match = OSMR0; + OSMR0 = initial_match + ticks * LATCH; + match_posponed = 1; + } +} + +static irqreturn_t +pxa_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + if (match_posponed) { + match_posponed = 0; + OSMR0 = initial_match; + if ( (signed long)(initial_match - OSCR) <= 8 ) + return pxa_timer_interrupt(irq, dev_id, regs); + } + return IRQ_NONE; +} + +static struct dyn_tick_timer pxa_dyn_tick = { + .enable = pxa_dyn_tick_enable_disable, + .disable = pxa_dyn_tick_enable_disable, + .reprogram = pxa_dyn_tick_reprogram, + .handler = pxa_dyn_tick_handler, +}; +#endif + #ifdef CONFIG_PM static unsigned long osmr[4], oier; @@ -161,4 +210,7 @@ struct sys_timer pxa_timer = { .suspend = pxa_timer_suspend, .resume = pxa_timer_resume, .offset = pxa_gettimeoffset, +#ifdef CONFIG_NO_IDLE_HZ + .dyn_tick = &pxa_dyn_tick, +#endif }; |