xref: /linux/arch/arm/mach-rpc/irq.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 #include <linux/init.h>
2 #include <linux/list.h>
3 #include <linux/io.h>
4 
5 #include <asm/mach/irq.h>
6 #include <asm/hardware/iomd.h>
7 #include <asm/irq.h>
8 #include <asm/fiq.h>
9 
10 static void iomd_ack_irq_a(struct irq_data *d)
11 {
12 	unsigned int val, mask;
13 
14 	mask = 1 << d->irq;
15 	val = iomd_readb(IOMD_IRQMASKA);
16 	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
17 	iomd_writeb(mask, IOMD_IRQCLRA);
18 }
19 
20 static void iomd_mask_irq_a(struct irq_data *d)
21 {
22 	unsigned int val, mask;
23 
24 	mask = 1 << d->irq;
25 	val = iomd_readb(IOMD_IRQMASKA);
26 	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
27 }
28 
29 static void iomd_unmask_irq_a(struct irq_data *d)
30 {
31 	unsigned int val, mask;
32 
33 	mask = 1 << d->irq;
34 	val = iomd_readb(IOMD_IRQMASKA);
35 	iomd_writeb(val | mask, IOMD_IRQMASKA);
36 }
37 
38 static struct irq_chip iomd_a_chip = {
39 	.irq_ack	= iomd_ack_irq_a,
40 	.irq_mask	= iomd_mask_irq_a,
41 	.irq_unmask	= iomd_unmask_irq_a,
42 };
43 
44 static void iomd_mask_irq_b(struct irq_data *d)
45 {
46 	unsigned int val, mask;
47 
48 	mask = 1 << (d->irq & 7);
49 	val = iomd_readb(IOMD_IRQMASKB);
50 	iomd_writeb(val & ~mask, IOMD_IRQMASKB);
51 }
52 
53 static void iomd_unmask_irq_b(struct irq_data *d)
54 {
55 	unsigned int val, mask;
56 
57 	mask = 1 << (d->irq & 7);
58 	val = iomd_readb(IOMD_IRQMASKB);
59 	iomd_writeb(val | mask, IOMD_IRQMASKB);
60 }
61 
62 static struct irq_chip iomd_b_chip = {
63 	.irq_ack	= iomd_mask_irq_b,
64 	.irq_mask	= iomd_mask_irq_b,
65 	.irq_unmask	= iomd_unmask_irq_b,
66 };
67 
68 static void iomd_mask_irq_dma(struct irq_data *d)
69 {
70 	unsigned int val, mask;
71 
72 	mask = 1 << (d->irq & 7);
73 	val = iomd_readb(IOMD_DMAMASK);
74 	iomd_writeb(val & ~mask, IOMD_DMAMASK);
75 }
76 
77 static void iomd_unmask_irq_dma(struct irq_data *d)
78 {
79 	unsigned int val, mask;
80 
81 	mask = 1 << (d->irq & 7);
82 	val = iomd_readb(IOMD_DMAMASK);
83 	iomd_writeb(val | mask, IOMD_DMAMASK);
84 }
85 
86 static struct irq_chip iomd_dma_chip = {
87 	.irq_ack	= iomd_mask_irq_dma,
88 	.irq_mask	= iomd_mask_irq_dma,
89 	.irq_unmask	= iomd_unmask_irq_dma,
90 };
91 
92 static void iomd_mask_irq_fiq(struct irq_data *d)
93 {
94 	unsigned int val, mask;
95 
96 	mask = 1 << (d->irq & 7);
97 	val = iomd_readb(IOMD_FIQMASK);
98 	iomd_writeb(val & ~mask, IOMD_FIQMASK);
99 }
100 
101 static void iomd_unmask_irq_fiq(struct irq_data *d)
102 {
103 	unsigned int val, mask;
104 
105 	mask = 1 << (d->irq & 7);
106 	val = iomd_readb(IOMD_FIQMASK);
107 	iomd_writeb(val | mask, IOMD_FIQMASK);
108 }
109 
110 static struct irq_chip iomd_fiq_chip = {
111 	.irq_ack	= iomd_mask_irq_fiq,
112 	.irq_mask	= iomd_mask_irq_fiq,
113 	.irq_unmask	= iomd_unmask_irq_fiq,
114 };
115 
116 extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
117 
118 void __init rpc_init_irq(void)
119 {
120 	unsigned int irq, clr, set = 0;
121 
122 	iomd_writeb(0, IOMD_IRQMASKA);
123 	iomd_writeb(0, IOMD_IRQMASKB);
124 	iomd_writeb(0, IOMD_FIQMASK);
125 	iomd_writeb(0, IOMD_DMAMASK);
126 
127 	set_fiq_handler(&rpc_default_fiq_start,
128 		&rpc_default_fiq_end - &rpc_default_fiq_start);
129 
130 	for (irq = 0; irq < NR_IRQS; irq++) {
131 		clr = IRQ_NOREQUEST;
132 
133 		if (irq <= 6 || (irq >= 9 && irq <= 15))
134 			clr |= IRQ_NOPROBE;
135 
136 		if (irq == 21 || (irq >= 16 && irq <= 19) ||
137 		    irq == IRQ_KEYBOARDTX)
138 			set |= IRQ_NOAUTOEN;
139 
140 		switch (irq) {
141 		case 0 ... 7:
142 			irq_set_chip_and_handler(irq, &iomd_a_chip,
143 						 handle_level_irq);
144 			irq_modify_status(irq, clr, set);
145 			break;
146 
147 		case 8 ... 15:
148 			irq_set_chip_and_handler(irq, &iomd_b_chip,
149 						 handle_level_irq);
150 			irq_modify_status(irq, clr, set);
151 			break;
152 
153 		case 16 ... 21:
154 			irq_set_chip_and_handler(irq, &iomd_dma_chip,
155 						 handle_level_irq);
156 			irq_modify_status(irq, clr, set);
157 			break;
158 
159 		case 64 ... 71:
160 			irq_set_chip(irq, &iomd_fiq_chip);
161 			irq_modify_status(irq, clr, set);
162 			break;
163 		}
164 	}
165 
166 	init_FIQ(FIQ_START);
167 }
168 
169