diff options
Diffstat (limited to 'arch/arm/plat-samsung/irq-vic-timer.c')
-rw-r--r-- | arch/arm/plat-samsung/irq-vic-timer.c | 69 |
1 files changed, 26 insertions, 43 deletions
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index d6ad66ab9290..a607546ddbd0 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c | |||
@@ -28,60 +28,43 @@ static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) | |||
28 | } | 28 | } |
29 | 29 | ||
30 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ | 30 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ |
31 | 31 | static void s3c_irq_timer_ack(struct irq_data *d) | |
32 | static void s3c_irq_timer_mask(struct irq_data *data) | ||
33 | { | ||
34 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
35 | u32 mask = (u32)data->chip_data; | ||
36 | |||
37 | reg &= 0x1f; /* mask out pending interrupts */ | ||
38 | reg &= ~mask; | ||
39 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
40 | } | ||
41 | |||
42 | static void s3c_irq_timer_unmask(struct irq_data *data) | ||
43 | { | 32 | { |
44 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | 33 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
45 | u32 mask = (u32)data->chip_data; | 34 | u32 mask = (1 << 5) << (d->irq - gc->irq_base); |
46 | 35 | ||
47 | reg &= 0x1f; /* mask out pending interrupts */ | 36 | irq_reg_writel(mask | gc->mask_cache, gc->reg_base); |
48 | reg |= mask; | ||
49 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
50 | } | 37 | } |
51 | 38 | ||
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 | |||
69 | /** | 39 | /** |
70 | * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\ | 40 | * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\ |
71 | * @parent_irq: The parent IRQ on the VIC for the timer. | 41 | * @num: Number of timers to initialize |
72 | * @timer_irq: The IRQ to be used for the timer. | 42 | * @timer_irq: Base IRQ number to be used for the timers. |
73 | * | 43 | * |
74 | * Register the necessary IRQ chaining and support for the timer IRQs | 44 | * Register the necessary IRQ chaining and support for the timer IRQs |
75 | * chained of the VIC. | 45 | * chained of the VIC. |
76 | */ | 46 | */ |
77 | void __init s3c_init_vic_timer_irq(unsigned int parent_irq, | 47 | void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq) |
78 | 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); | 55 | s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq, |
82 | irq_set_handler_data(parent_irq, (void *)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); | 66 | for (i = 0; i < num; i++, timer_irq++) { |
85 | irq_set_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0))); | 67 | irq_set_chained_handler(pirq[i], s3c_irq_demux_vic_timer); |
86 | set_irq_flags(timer_irq, IRQF_VALID); | 68 | irq_set_handler_data(pirq[i], (void *)timer_irq); |
69 | } | ||
87 | } | 70 | } |