Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* arch/arm/mach-lh7a40x/irq-lh7a404.c |
2 | * | |
3 | * Copyright (C) 2004 Logic Product Development | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or | |
6 | * modify it under the terms of the GNU General Public License | |
7 | * version 2 as published by the Free Software Foundation. | |
8 | * | |
9 | */ | |
10 | ||
11 | #include <linux/init.h> | |
12 | #include <linux/module.h> | |
13 | #include <linux/interrupt.h> | |
1da177e4 | 14 | |
be509729 | 15 | #include <asm/arch/hardware.h> |
1da177e4 LT |
16 | #include <asm/irq.h> |
17 | #include <asm/mach/irq.h> | |
1da177e4 LT |
18 | #include <asm/arch/irqs.h> |
19 | ||
411ef7f4 RK |
20 | #include "common.h" |
21 | ||
1da177e4 LT |
22 | #define USE_PRIORITIES |
23 | ||
24 | /* See Documentation/arm/Sharp-LH/VectoredInterruptController for more | |
25 | * information on using the vectored interrupt controller's | |
26 | * prioritizing feature. */ | |
27 | ||
28 | static unsigned char irq_pri_vic1[] = { | |
29 | #if defined (USE_PRIORITIES) | |
638b2666 MS |
30 | IRQ_GPIO3INTR, /* CPLD */ |
31 | IRQ_DMAM2P4, IRQ_DMAM2P5, /* AC97 */ | |
1da177e4 LT |
32 | #endif |
33 | }; | |
34 | static unsigned char irq_pri_vic2[] = { | |
35 | #if defined (USE_PRIORITIES) | |
638b2666 MS |
36 | IRQ_T3UI, /* Timer */ |
37 | IRQ_GPIO7INTR, /* CPLD */ | |
1da177e4 | 38 | IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR, |
638b2666 MS |
39 | IRQ_LCDINTR, /* LCD */ |
40 | IRQ_TSCINTR, /* ADC/Touchscreen */ | |
1da177e4 LT |
41 | #endif |
42 | }; | |
43 | ||
44 | /* CPU IRQ handling */ | |
45 | ||
46 | static void lh7a404_vic1_mask_irq (u32 irq) | |
47 | { | |
48 | VIC1_INTENCLR = (1 << irq); | |
49 | } | |
50 | ||
51 | static void lh7a404_vic1_unmask_irq (u32 irq) | |
52 | { | |
53 | VIC1_INTEN = (1 << irq); | |
54 | } | |
55 | ||
56 | static void lh7a404_vic2_mask_irq (u32 irq) | |
57 | { | |
58 | VIC2_INTENCLR = (1 << (irq - 32)); | |
59 | } | |
60 | ||
61 | static void lh7a404_vic2_unmask_irq (u32 irq) | |
62 | { | |
63 | VIC2_INTEN = (1 << (irq - 32)); | |
64 | } | |
65 | ||
66 | static void lh7a404_vic1_ack_gpio_irq (u32 irq) | |
67 | { | |
68 | GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq)); | |
69 | VIC1_INTENCLR = (1 << irq); | |
70 | } | |
71 | ||
72 | static void lh7a404_vic2_ack_gpio_irq (u32 irq) | |
73 | { | |
74 | GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq)); | |
75 | VIC2_INTENCLR = (1 << irq); | |
76 | } | |
77 | ||
38c677cb DB |
78 | static struct irq_chip lh7a404_vic1_chip = { |
79 | .name = "VIC1", | |
1da177e4 LT |
80 | .ack = lh7a404_vic1_mask_irq, /* Because level-triggered */ |
81 | .mask = lh7a404_vic1_mask_irq, | |
82 | .unmask = lh7a404_vic1_unmask_irq, | |
83 | }; | |
84 | ||
38c677cb DB |
85 | static struct irq_chip lh7a404_vic2_chip = { |
86 | .name = "VIC2", | |
1da177e4 LT |
87 | .ack = lh7a404_vic2_mask_irq, /* Because level-triggered */ |
88 | .mask = lh7a404_vic2_mask_irq, | |
89 | .unmask = lh7a404_vic2_unmask_irq, | |
90 | }; | |
91 | ||
38c677cb DB |
92 | static struct irq_chip lh7a404_gpio_vic1_chip = { |
93 | .name = "GPIO-VIC1", | |
1da177e4 LT |
94 | .ack = lh7a404_vic1_ack_gpio_irq, |
95 | .mask = lh7a404_vic1_mask_irq, | |
96 | .unmask = lh7a404_vic1_unmask_irq, | |
97 | }; | |
98 | ||
38c677cb DB |
99 | static struct irq_chip lh7a404_gpio_vic2_chip = { |
100 | .name = "GPIO-VIC2", | |
1da177e4 LT |
101 | .ack = lh7a404_vic2_ack_gpio_irq, |
102 | .mask = lh7a404_vic2_mask_irq, | |
103 | .unmask = lh7a404_vic2_unmask_irq, | |
104 | }; | |
105 | ||
106 | /* IRQ initialization */ | |
107 | ||
638b2666 MS |
108 | #if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404) |
109 | extern void* branch_irq_lh7a400; | |
110 | #endif | |
111 | ||
1da177e4 LT |
112 | void __init lh7a404_init_irq (void) |
113 | { | |
114 | int irq; | |
115 | ||
638b2666 MS |
116 | #if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404) |
117 | #define NOP 0xe1a00000 /* mov r0, r0 */ | |
118 | branch_irq_lh7a400 = NOP; | |
119 | #endif | |
120 | ||
1da177e4 LT |
121 | VIC1_INTENCLR = 0xffffffff; |
122 | VIC2_INTENCLR = 0xffffffff; | |
123 | VIC1_INTSEL = 0; /* All IRQs */ | |
124 | VIC2_INTSEL = 0; /* All IRQs */ | |
125 | VIC1_NVADDR = VA_VIC1DEFAULT; | |
126 | VIC2_NVADDR = VA_VIC2DEFAULT; | |
127 | VIC1_VECTADDR = 0; | |
128 | VIC2_VECTADDR = 0; | |
129 | ||
130 | GPIO_GPIOFINTEN = 0x00; /* Disable all GPIOF interrupts */ | |
131 | barrier (); | |
132 | ||
133 | /* Install prioritized interrupts, if there are any. */ | |
134 | /* The | 0x20*/ | |
135 | for (irq = 0; irq < 16; ++irq) { | |
136 | (&VIC1_VAD0)[irq] | |
137 | = (irq < ARRAY_SIZE (irq_pri_vic1)) | |
138 | ? (irq_pri_vic1[irq] | VA_VECTORED) : 0; | |
139 | (&VIC1_VECTCNTL0)[irq] | |
140 | = (irq < ARRAY_SIZE (irq_pri_vic1)) | |
141 | ? (irq_pri_vic1[irq] | VIC_CNTL_ENABLE) : 0; | |
142 | (&VIC2_VAD0)[irq] | |
143 | = (irq < ARRAY_SIZE (irq_pri_vic2)) | |
144 | ? (irq_pri_vic2[irq] | VA_VECTORED) : 0; | |
145 | (&VIC2_VECTCNTL0)[irq] | |
146 | = (irq < ARRAY_SIZE (irq_pri_vic2)) | |
147 | ? (irq_pri_vic2[irq] | VIC_CNTL_ENABLE) : 0; | |
148 | } | |
149 | ||
150 | for (irq = 0; irq < NR_IRQS; ++irq) { | |
151 | switch (irq) { | |
152 | case IRQ_GPIO0INTR: | |
153 | case IRQ_GPIO1INTR: | |
154 | case IRQ_GPIO2INTR: | |
155 | case IRQ_GPIO3INTR: | |
156 | case IRQ_GPIO4INTR: | |
157 | case IRQ_GPIO5INTR: | |
158 | case IRQ_GPIO6INTR: | |
159 | case IRQ_GPIO7INTR: | |
160 | set_irq_chip (irq, irq < 32 | |
161 | ? &lh7a404_gpio_vic1_chip | |
162 | : &lh7a404_gpio_vic2_chip); | |
10dd5ce2 | 163 | set_irq_handler (irq, handle_level_irq); /* OK default */ |
1da177e4 LT |
164 | break; |
165 | default: | |
166 | set_irq_chip (irq, irq < 32 | |
167 | ? &lh7a404_vic1_chip | |
168 | : &lh7a404_vic2_chip); | |
10dd5ce2 | 169 | set_irq_handler (irq, handle_level_irq); |
1da177e4 LT |
170 | } |
171 | set_irq_flags (irq, IRQF_VALID); | |
172 | } | |
173 | ||
174 | lh7a40x_init_board_irq (); | |
175 | } |