]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - arch/arm/mach-tcc8k/irq.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[linux-2.6.git] / arch / arm / mach-tcc8k / irq.c
1 /*
2  * Copyright (C) Telechips, Inc.
3  * Copyright (C) 2009-2010 Hans J. Koch <hjk@linutronix.de>
4  *
5  * Licensed under the terms of the GNU GPL version 2.
6  */
7
8 #include <linux/init.h>
9 #include <linux/interrupt.h>
10 #include <linux/io.h>
11
12 #include <asm/irq.h>
13 #include <asm/mach/irq.h>
14
15 #include <mach/tcc8k-regs.h>
16 #include <mach/irqs.h>
17
18 #include "common.h"
19
20 /* Disable IRQ */
21 static void tcc8000_mask_ack_irq0(struct irq_data *d)
22 {
23         PIC0_IEN &= ~(1 << d->irq);
24         PIC0_CREQ |=  (1 << d->irq);
25 }
26
27 static void tcc8000_mask_ack_irq1(struct irq_data *d)
28 {
29         PIC1_IEN &= ~(1 << (d->irq - 32));
30         PIC1_CREQ |= (1 << (d->irq - 32));
31 }
32
33 static void tcc8000_mask_irq0(struct irq_data *d)
34 {
35         PIC0_IEN &= ~(1 << d->irq);
36 }
37
38 static void tcc8000_mask_irq1(struct irq_data *d)
39 {
40         PIC1_IEN &= ~(1 << (d->irq - 32));
41 }
42
43 static void tcc8000_ack_irq0(struct irq_data *d)
44 {
45         PIC0_CREQ |=  (1 << d->irq);
46 }
47
48 static void tcc8000_ack_irq1(struct irq_data *d)
49 {
50         PIC1_CREQ |= (1 << (d->irq - 32));
51 }
52
53 /* Enable IRQ */
54 static void tcc8000_unmask_irq0(struct irq_data *d)
55 {
56         PIC0_IEN |= (1 << d->irq);
57         PIC0_INTOEN |= (1 << d->irq);
58 }
59
60 static void tcc8000_unmask_irq1(struct irq_data *d)
61 {
62         PIC1_IEN |= (1 << (d->irq - 32));
63         PIC1_INTOEN |= (1 << (d->irq - 32));
64 }
65
66 static struct irq_chip tcc8000_irq_chip0 = {
67         .name           = "tcc_irq0",
68         .irq_mask       = tcc8000_mask_irq0,
69         .irq_ack        = tcc8000_ack_irq0,
70         .irq_mask_ack   = tcc8000_mask_ack_irq0,
71         .irq_unmask     = tcc8000_unmask_irq0,
72 };
73
74 static struct irq_chip tcc8000_irq_chip1 = {
75         .name           = "tcc_irq1",
76         .irq_mask       = tcc8000_mask_irq1,
77         .irq_ack        = tcc8000_ack_irq1,
78         .irq_mask_ack   = tcc8000_mask_ack_irq1,
79         .irq_unmask     = tcc8000_unmask_irq1,
80 };
81
82 void __init tcc8k_init_irq(void)
83 {
84         int irqno;
85
86         /* Mask and clear all interrupts */
87         PIC0_IEN = 0x00000000;
88         PIC0_CREQ = 0xffffffff;
89         PIC1_IEN = 0x00000000;
90         PIC1_CREQ = 0xffffffff;
91
92         PIC0_MEN0 = 0x00000003;
93         PIC1_MEN1 = 0x00000003;
94         PIC1_MEN = 0x00000003;
95
96         /* let all IRQs be level triggered */
97         PIC0_TMODE = 0xffffffff;
98         PIC1_TMODE = 0xffffffff;
99         /* all IRQs are IRQs (not FIQs) */
100         PIC0_IRQSEL = 0xffffffff;
101         PIC1_IRQSEL = 0xffffffff;
102
103         for (irqno = 0; irqno < NR_IRQS; irqno++) {
104                 if (irqno < 32)
105                         set_irq_chip(irqno, &tcc8000_irq_chip0);
106                 else
107                         set_irq_chip(irqno, &tcc8000_irq_chip1);
108                 set_irq_handler(irqno, handle_level_irq);
109                 set_irq_flags(irqno, IRQF_VALID);
110         }
111 }