Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd
[pandora-kernel.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(unsigned int irq)
22 {
23         PIC0_IEN &= ~(1 << irq);
24         PIC0_CREQ |=  (1 << irq);
25 }
26
27 static void tcc8000_mask_ack_irq1(unsigned int irq)
28 {
29         PIC1_IEN &= ~(1 << (irq - 32));
30         PIC1_CREQ |= (1 << (irq - 32));
31 }
32
33 static void tcc8000_mask_irq0(unsigned int irq)
34 {
35         PIC0_IEN &= ~(1 << irq);
36 }
37
38 static void tcc8000_mask_irq1(unsigned int irq)
39 {
40         PIC1_IEN &= ~(1 << (irq - 32));
41 }
42
43 static void tcc8000_ack_irq0(unsigned int irq)
44 {
45         PIC0_CREQ |=  (1 << irq);
46 }
47
48 static void tcc8000_ack_irq1(unsigned int irq)
49 {
50         PIC1_CREQ |= (1 << (irq - 32));
51 }
52
53 /* Enable IRQ */
54 static void tcc8000_unmask_irq0(unsigned int irq)
55 {
56         PIC0_IEN |= (1 << irq);
57         PIC0_INTOEN |= (1 << irq);
58 }
59
60 static void tcc8000_unmask_irq1(unsigned int irq)
61 {
62         PIC1_IEN |= (1 << (irq - 32));
63         PIC1_INTOEN |= (1 << (irq - 32));
64 }
65
66 static struct irq_chip tcc8000_irq_chip0 = {
67         .name           = "tcc_irq0",
68         .mask           = tcc8000_mask_irq0,
69         .ack            = tcc8000_ack_irq0,
70         .mask_ack       = tcc8000_mask_ack_irq0,
71         .unmask         = tcc8000_unmask_irq0,
72 };
73
74 static struct irq_chip tcc8000_irq_chip1 = {
75         .name           = "tcc_irq1",
76         .mask           = tcc8000_mask_irq1,
77         .ack            = tcc8000_ack_irq1,
78         .mask_ack       = tcc8000_mask_ack_irq1,
79         .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 }