Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: SAMSUNG: Convert irq-vic-timer to generic irq chip

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Thomas Gleixner and committed by
Mark Brown
2d2e1d3c ad739dcf

+29 -55
+1 -6
arch/arm/mach-s3c64xx/irq.c
··· 58 58 vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0); 59 59 60 60 /* add the timer sub-irqs */ 61 - 62 - s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0); 63 - s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1); 64 - s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2); 65 - s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3); 66 - s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4); 61 + s3c_init_vic_timer_irq(5, IRQ_TIMER0); 67 62 68 63 s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); 69 64 }
+1 -5
arch/arm/plat-s5p/irq.c
··· 64 64 vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); 65 65 #endif 66 66 67 - s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0); 68 - s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1); 69 - s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2); 70 - s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3); 71 - s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4); 67 + s3c_init_vic_timer_irq(5, IRQ_TIMER0); 72 68 73 69 s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); 74 70 }
+1 -1
arch/arm/plat-samsung/include/plat/irq-vic-timer.h
··· 10 10 * published by the Free Software Foundation. 11 11 */ 12 12 13 - extern void s3c_init_vic_timer_irq(unsigned int vic, unsigned int timer); 13 + extern void s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq);
+26 -43
arch/arm/plat-samsung/irq-vic-timer.c
··· 28 28 } 29 29 30 30 /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ 31 - 32 - static void s3c_irq_timer_mask(struct irq_data *data) 31 + static void s3c_irq_timer_ack(struct irq_data *d) 33 32 { 34 - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 35 - u32 mask = (u32)data->chip_data; 33 + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 34 + u32 mask = (1 << 5) << (d->irq - gc->irq_base); 36 35 37 - reg &= 0x1f; /* mask out pending interrupts */ 38 - reg &= ~mask; 39 - __raw_writel(reg, S3C64XX_TINT_CSTAT); 36 + irq_reg_writel(mask | gc->mask_cache, gc->reg_base); 40 37 } 41 - 42 - static void s3c_irq_timer_unmask(struct irq_data *data) 43 - { 44 - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 45 - u32 mask = (u32)data->chip_data; 46 - 47 - reg &= 0x1f; /* mask out pending interrupts */ 48 - reg |= mask; 49 - __raw_writel(reg, S3C64XX_TINT_CSTAT); 50 - } 51 - 52 - static void s3c_irq_timer_ack(struct irq_data *data) 53 - { 54 - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 55 - u32 mask = (u32)data->chip_data; 56 - 57 - reg &= 0x1f; 58 - reg |= mask << 5; 59 - __raw_writel(reg, S3C64XX_TINT_CSTAT); 60 - } 61 - 62 - static struct irq_chip s3c_irq_timer = { 63 - .name = "s3c-timer", 64 - .irq_mask = s3c_irq_timer_mask, 65 - .irq_unmask = s3c_irq_timer_unmask, 66 - .irq_ack = s3c_irq_timer_ack, 67 - }; 68 38 69 39 /** 70 40 * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\ 71 - * @parent_irq: The parent IRQ on the VIC for the timer. 72 - * @timer_irq: The IRQ to be used for the timer. 41 + * @num: Number of timers to initialize 42 + * @timer_irq: Base IRQ number to be used for the timers. 73 43 * 74 44 * Register the necessary IRQ chaining and support for the timer IRQs 75 45 * chained of the VIC. 76 46 */ 77 - void __init s3c_init_vic_timer_irq(unsigned int parent_irq, 78 - unsigned int timer_irq) 47 + void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq) 79 48 { 49 + unsigned int pirq[5] = { IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC, 50 + IRQ_TIMER3_VIC, IRQ_TIMER4_VIC }; 51 + struct irq_chip_generic *s3c_tgc; 52 + struct irq_chip_type *ct; 53 + unsigned int i; 80 54 81 - irq_set_chained_handler(parent_irq, s3c_irq_demux_vic_timer); 82 - irq_set_handler_data(parent_irq, (void *)timer_irq); 55 + s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq, 56 + S3C64XX_TINT_CSTAT, handle_level_irq); 57 + ct = s3c_tgc->chip_types; 58 + ct->chip.irq_mask = irq_gc_mask_clr_bit; 59 + ct->chip.irq_unmask = irq_gc_mask_set_bit; 60 + ct->chip.irq_ack = s3c_irq_timer_ack; 61 + irq_setup_generic_chip(s3c_tgc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, 62 + IRQ_NOREQUEST | IRQ_NOPROBE, 0); 63 + /* Clear the upper bits of the mask_cache*/ 64 + s3c_tgc->mask_cache &= 0x1f; 83 65 84 - irq_set_chip_and_handler(timer_irq, &s3c_irq_timer, handle_level_irq); 85 - irq_set_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0))); 86 - set_irq_flags(timer_irq, IRQF_VALID); 66 + for (i = 0; i < num; i++, timer_irq++) { 67 + irq_set_chained_handler(pirq[i], s3c_irq_demux_vic_timer); 68 + irq_set_handler_data(pirq[i], (void *)timer_irq); 69 + } 87 70 }