aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pnx4008/irq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-20 17:49:00 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-20 17:49:00 -0400
commitff9144530e9cfe8923e00172e3f8ff83c3b8ff8b (patch)
treec64a9528dde590b9f3174125ad361f46ee30bba8 /arch/arm/mach-pnx4008/irq.c
parent25f42b6af09e34c3f92107b36b5aa6edc2fdba2f (diff)
parent96ce2385dd2817da549910001a69ac0a2762a1b9 (diff)
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm: (22 commits) [ARM] 3559/1: S3C2442: core and serial port [ARM] 3557/1: S3C24XX: centralise and cleanup uart registration [ARM] 3558/1: SMDK24XX: LED platform devices [ARM] 3534/1: add spi support to lubbock platform [ARM] 3554/1: ARM: Fix dyntick locking [ARM] 3553/1: S3C24XX: earlier print of cpu idcode info [ARM] 3552/1: S3C24XX: Move VA of GPIO for low-level debug [ARM] 3551/1: S3C24XX: PM code failes to compile with CONFIG_DCACHE_WRITETHROUGH [ARM] 3550/1: OSIRIS: fix serial port map for 1:1 [ARM] 3548/1: Fix the ARMv6 CPU id in compressed/head.S [ARM] 3335/1: Old-abi Thumb sys_syscall broken [ARM] 3467/1: [3/3] Support for Philips PNX4008 platform: defconfig [ARM] 3466/1: [2/3] Support for Philips PNX4008 platform: chip support [ARM] 3465/1: [1/3] Support for Philips PNX4008 platform: headers [ARM] 3407/1: lpd7x: documetation update [ARM] 3406/1: lpd7x: compilation fix for smc91x [ARM] 3405/1: lpd7a40x: CPLD ssp driver [ARM] 3404/1: lpd7a40x: AMBA CLCD support [ARM] 3403/1: lpd7a40x: updated default configurations [ARM] 3402/1: lpd7a40x: serial driver bug fix ...
Diffstat (limited to 'arch/arm/mach-pnx4008/irq.c')
-rw-r--r--arch/arm/mach-pnx4008/irq.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
new file mode 100644
index 000000000000..9b0a8e084e99
--- /dev/null
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -0,0 +1,121 @@
1/*
2 * arch/arm/mach-pnx4008/irq.c
3 *
4 * PNX4008 IRQ controller driver
5 *
6 * Author: Dmitry Chigirev <source@mvista.com>
7 *
8 * Based on reference code received from Philips:
9 * Copyright (C) 2003 Philips Semiconductors
10 *
11 * 2005 (c) MontaVista Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15 */
16
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <linux/mm.h>
20#include <linux/interrupt.h>
21#include <linux/list.h>
22#include <linux/init.h>
23#include <linux/ioport.h>
24#include <linux/device.h>
25#include <asm/hardware.h>
26#include <asm/irq.h>
27#include <asm/io.h>
28#include <asm/setup.h>
29#include <asm/mach-types.h>
30#include <asm/pgtable.h>
31#include <asm/page.h>
32#include <asm/system.h>
33#include <asm/mach/arch.h>
34#include <asm/mach/irq.h>
35#include <asm/mach/map.h>
36#include <asm/arch/irq.h>
37
38static u8 pnx4008_irq_type[NR_IRQS] = PNX4008_IRQ_TYPES;
39
40static void pnx4008_mask_irq(unsigned int irq)
41{
42 __raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq)); /* mask interrupt */
43}
44
45static void pnx4008_unmask_irq(unsigned int irq)
46{
47 __raw_writel(__raw_readl(INTC_ER(irq)) | INTC_BIT(irq), INTC_ER(irq)); /* unmask interrupt */
48}
49
50static void pnx4008_mask_ack_irq(unsigned int irq)
51{
52 __raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq)); /* mask interrupt */
53 __raw_writel(INTC_BIT(irq), INTC_SR(irq)); /* clear interrupt status */
54}
55
56static int pnx4008_set_irq_type(unsigned int irq, unsigned int type)
57{
58 switch (type) {
59 case IRQT_RISING:
60 __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
61 __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /*rising edge */
62 set_irq_handler(irq, do_edge_IRQ);
63 break;
64 case IRQT_FALLING:
65 __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */
66 __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*falling edge */
67 set_irq_handler(irq, do_edge_IRQ);
68 break;
69 case IRQT_LOW:
70 __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
71 __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*low level */
72 set_irq_handler(irq, do_level_IRQ);
73 break;
74 case IRQT_HIGH:
75 __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */
76 __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /* high level */
77 set_irq_handler(irq, do_level_IRQ);
78 break;
79
80 /* IRQT_BOTHEDGE is not supported */
81 default:
82 printk(KERN_ERR "PNX4008 IRQ: Unsupported irq type %d\n", type);
83 return -1;
84 }
85 return 0;
86}
87
88static struct irqchip pnx4008_irq_chip = {
89 .ack = pnx4008_mask_ack_irq,
90 .mask = pnx4008_mask_irq,
91 .unmask = pnx4008_unmask_irq,
92 .set_type = pnx4008_set_irq_type,
93};
94
95void __init pnx4008_init_irq(void)
96{
97 unsigned int i;
98
99 /* configure and enable IRQ 0,1,30,31 (cascade interrupts) mask all others */
100 pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]);
101 pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]);
102 pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]);
103 pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]);
104
105 __raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
106 (1 << SUB2_IRQ_N) | (1 << SUB1_IRQ_N),
107 INTC_ER(MAIN_BASE_INT));
108 __raw_writel(0, INTC_ER(SIC1_BASE_INT));
109 __raw_writel(0, INTC_ER(SIC2_BASE_INT));
110
111 /* configure all other IRQ's */
112 for (i = 0; i < NR_IRQS; i++) {
113 if (i == SUB2_FIQ_N || i == SUB1_FIQ_N ||
114 i == SUB2_IRQ_N || i == SUB1_IRQ_N)
115 continue;
116 set_irq_flags(i, IRQF_VALID);
117 set_irq_chip(i, &pnx4008_irq_chip);
118 pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
119 }
120}
121