2 * linux/arch/arm/mach-imx/irq.c
4 * Copyright (C) 1999 ARM Limited
5 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * 03/03/2004 Sascha Hauer <sascha@saschahauer.de>
22 * Copied from the motorola bsp package and added gpio demux
26 #include <linux/init.h>
27 #include <linux/list.h>
28 #include <linux/timer.h>
30 #include <asm/hardware.h>
34 #include <asm/mach/irq.h>
38 * We simply use the ENABLE DISABLE registers inside of the IMX
39 * to turn on/off specific interrupts. FIXME- We should
40 * also add support for the accelerated interrupt controller
41 * by putting offets to irq jump code in the appropriate
46 #define INTENNUM_OFF 0x8
47 #define INTDISNUM_OFF 0xC
49 #define VA_AITC_BASE IO_ADDRESS(IMX_AITC_BASE)
50 #define IMX_AITC_INTDISNUM (VA_AITC_BASE + INTDISNUM_OFF)
51 #define IMX_AITC_INTENNUM (VA_AITC_BASE + INTENNUM_OFF)
54 #define DEBUG_IRQ(fmt...) printk(fmt)
56 #define DEBUG_IRQ(fmt...) do { } while (0)
60 imx_mask_irq(unsigned int irq
)
62 __raw_writel(irq
, IMX_AITC_INTDISNUM
);
66 imx_unmask_irq(unsigned int irq
)
68 __raw_writel(irq
, IMX_AITC_INTENNUM
);
72 imx_gpio_irq_type(unsigned int _irq
, unsigned int type
)
74 unsigned int irq_type
= 0, irq
, reg
, bit
;
76 irq
= _irq
- IRQ_GPIOA(0);
78 bit
= 1 << (irq
% 32);
80 if (type
== IRQT_PROBE
) {
81 /* Don't mess with enabled GPIOs using preconfigured edges or
82 GPIOs set to alternate function during probe */
83 /* TODO: support probe */
84 // if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &
87 // if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
89 // type = __IRQT_RISEDGE | __IRQT_FALEDGE;
95 DEBUG_IRQ("setting type of irq %d to ", _irq
);
97 if (type
& __IRQT_RISEDGE
) {
98 DEBUG_IRQ("rising edges\n");
101 if (type
& __IRQT_FALEDGE
) {
102 DEBUG_IRQ("falling edges\n");
105 if (type
& __IRQT_LOWLVL
) {
106 DEBUG_IRQ("low level\n");
109 if (type
& __IRQT_HIGHLVL
) {
110 DEBUG_IRQ("high level\n");
115 ICR1(reg
) = (ICR1(reg
) & ~(0x3 << ((irq
% 16) * 2))) |
116 (irq_type
<< ((irq
% 16) * 2));
118 ICR2(reg
) = (ICR2(reg
) & ~(0x3 << ((irq
% 16) * 2))) |
119 (irq_type
<< ((irq
% 16) * 2));
127 imx_gpio_ack_irq(unsigned int irq
)
129 DEBUG_IRQ("%s: irq %d\n", __FUNCTION__
, irq
);
130 ISR(IRQ_TO_REG(irq
)) |= 1 << ((irq
- IRQ_GPIOA(0)) % 32);
134 imx_gpio_mask_irq(unsigned int irq
)
136 DEBUG_IRQ("%s: irq %d\n", __FUNCTION__
, irq
);
137 IMR(IRQ_TO_REG(irq
)) &= ~( 1 << ((irq
- IRQ_GPIOA(0)) % 32));
141 imx_gpio_unmask_irq(unsigned int irq
)
143 DEBUG_IRQ("%s: irq %d\n", __FUNCTION__
, irq
);
144 IMR(IRQ_TO_REG(irq
)) |= 1 << ((irq
- IRQ_GPIOA(0)) % 32);
148 imx_gpio_handler(unsigned int mask
, unsigned int irq
,
149 struct irqdesc
*desc
, struct pt_regs
*regs
)
151 desc
= irq_desc
+ irq
;
154 DEBUG_IRQ("handling irq %d\n", irq
);
155 desc
->handle(irq
, desc
, regs
);
164 imx_gpioa_demux_handler(unsigned int irq_unused
, struct irqdesc
*desc
,
165 struct pt_regs
*regs
)
167 unsigned int mask
, irq
;
171 imx_gpio_handler(mask
, irq
, desc
, regs
);
175 imx_gpiob_demux_handler(unsigned int irq_unused
, struct irqdesc
*desc
,
176 struct pt_regs
*regs
)
178 unsigned int mask
, irq
;
182 imx_gpio_handler(mask
, irq
, desc
, regs
);
186 imx_gpioc_demux_handler(unsigned int irq_unused
, struct irqdesc
*desc
,
187 struct pt_regs
*regs
)
189 unsigned int mask
, irq
;
193 imx_gpio_handler(mask
, irq
, desc
, regs
);
197 imx_gpiod_demux_handler(unsigned int irq_unused
, struct irqdesc
*desc
,
198 struct pt_regs
*regs
)
200 unsigned int mask
, irq
;
204 imx_gpio_handler(mask
, irq
, desc
, regs
);
207 static struct irqchip imx_internal_chip
= {
209 .mask
= imx_mask_irq
,
210 .unmask
= imx_unmask_irq
,
213 static struct irqchip imx_gpio_chip
= {
214 .ack
= imx_gpio_ack_irq
,
215 .mask
= imx_gpio_mask_irq
,
216 .unmask
= imx_gpio_unmask_irq
,
217 .type
= imx_gpio_irq_type
,
225 DEBUG_IRQ("Initializing imx interrupts\n");
227 /* Mask all interrupts initially */
233 for (irq
= 0; irq
< IMX_IRQS
; irq
++) {
234 set_irq_chip(irq
, &imx_internal_chip
);
235 set_irq_handler(irq
, do_level_IRQ
);
236 set_irq_flags(irq
, IRQF_VALID
);
239 for (irq
= IRQ_GPIOA(0); irq
< IRQ_GPIOD(32); irq
++) {
240 set_irq_chip(irq
, &imx_gpio_chip
);
241 set_irq_handler(irq
, do_edge_IRQ
);
242 set_irq_flags(irq
, IRQF_VALID
);
245 set_irq_chained_handler(GPIO_INT_PORTA
, imx_gpioa_demux_handler
);
246 set_irq_chained_handler(GPIO_INT_PORTB
, imx_gpiob_demux_handler
);
247 set_irq_chained_handler(GPIO_INT_PORTC
, imx_gpioc_demux_handler
);
248 set_irq_chained_handler(GPIO_INT_PORTD
, imx_gpiod_demux_handler
);
250 /* Disable all interrupts initially. */
251 /* In IMX this is done in the bootloader. */