1/*
2 *  linux/include/asm-arm/arch-rpc/irq.h
3 *
4 *  Copyright (C) 1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 *  Changelog:
11 *   10-10-1996	RMK	Brought up to date with arch-sa110eval
12 *   22-08-1998	RMK	Restructured IRQ routines
13 */
14#include <asm/hardware/iomd.h>
15#include <asm/io.h>
16
17#define fixup_irq(x) (x)
18
19static void rpc_mask_irq_ack_a(unsigned int irq)
20{
21	unsigned int val, mask;
22
23	mask = 1 << irq;
24	val = iomd_readb(IOMD_IRQMASKA);
25	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
26	iomd_writeb(mask, IOMD_IRQCLRA);
27}
28
29static void rpc_mask_irq_a(unsigned int irq)
30{
31	unsigned int val, mask;
32
33	mask = 1 << irq;
34	val = iomd_readb(IOMD_IRQMASKA);
35	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
36}
37
38static void rpc_unmask_irq_a(unsigned int irq)
39{
40	unsigned int val, mask;
41
42	mask = 1 << irq;
43	val = iomd_readb(IOMD_IRQMASKA);
44	iomd_writeb(val | mask, IOMD_IRQMASKA);
45}
46
47static void rpc_mask_irq_b(unsigned int irq)
48{
49	unsigned int val, mask;
50
51	mask = 1 << (irq & 7);
52	val = iomd_readb(IOMD_IRQMASKB);
53	iomd_writeb(val & ~mask, IOMD_IRQMASKB);
54}
55
56static void rpc_unmask_irq_b(unsigned int irq)
57{
58	unsigned int val, mask;
59
60	mask = 1 << (irq & 7);
61	val = iomd_readb(IOMD_IRQMASKB);
62	iomd_writeb(val | mask, IOMD_IRQMASKB);
63}
64
65static void rpc_mask_irq_dma(unsigned int irq)
66{
67	unsigned int val, mask;
68
69	mask = 1 << (irq & 7);
70	val = iomd_readb(IOMD_DMAMASK);
71	iomd_writeb(val & ~mask, IOMD_DMAMASK);
72}
73
74static void rpc_unmask_irq_dma(unsigned int irq)
75{
76	unsigned int val, mask;
77
78	mask = 1 << (irq & 7);
79	val = iomd_readb(IOMD_DMAMASK);
80	iomd_writeb(val | mask, IOMD_DMAMASK);
81}
82
83static void rpc_mask_irq_fiq(unsigned int irq)
84{
85	unsigned int val, mask;
86
87	mask = 1 << (irq & 7);
88	val = iomd_readb(IOMD_FIQMASK);
89	iomd_writeb(val & ~mask, IOMD_FIQMASK);
90}
91
92static void rpc_unmask_irq_fiq(unsigned int irq)
93{
94	unsigned int val, mask;
95
96	mask = 1 << (irq & 7);
97	val = iomd_readb(IOMD_FIQMASK);
98	iomd_writeb(val | mask, IOMD_FIQMASK);
99}
100
101static __inline__ void irq_init_irq(void)
102{
103	int irq;
104
105	iomd_writeb(0, IOMD_IRQMASKA);
106	iomd_writeb(0, IOMD_IRQMASKB);
107	iomd_writeb(0, IOMD_FIQMASK);
108	iomd_writeb(0, IOMD_DMAMASK);
109
110	for (irq = 0; irq < NR_IRQS; irq++) {
111		switch (irq) {
112		case 0 ... 6:
113			irq_desc[irq].probe_ok = 1;
114		case 7:
115			irq_desc[irq].valid    = 1;
116			irq_desc[irq].mask_ack = rpc_mask_irq_ack_a;
117			irq_desc[irq].mask     = rpc_mask_irq_a;
118			irq_desc[irq].unmask   = rpc_unmask_irq_a;
119			break;
120
121		case 9 ... 15:
122			irq_desc[irq].probe_ok = 1;
123		case 8:
124			irq_desc[irq].valid    = 1;
125			irq_desc[irq].mask_ack = rpc_mask_irq_b;
126			irq_desc[irq].mask     = rpc_mask_irq_b;
127			irq_desc[irq].unmask   = rpc_unmask_irq_b;
128			break;
129
130		case 16 ... 19:
131		case 21:
132			irq_desc[irq].noautoenable = 1;
133		case 20:
134			irq_desc[irq].valid    = 1;
135			irq_desc[irq].mask_ack = rpc_mask_irq_dma;
136			irq_desc[irq].mask     = rpc_mask_irq_dma;
137			irq_desc[irq].unmask   = rpc_unmask_irq_dma;
138			break;
139
140		case 64 ... 71:
141			irq_desc[irq].valid    = 1;
142			irq_desc[irq].mask_ack = rpc_mask_irq_fiq;
143			irq_desc[irq].mask     = rpc_mask_irq_fiq;
144			irq_desc[irq].unmask   = rpc_unmask_irq_fiq;
145			break;
146		}
147	}
148
149	irq_desc[IRQ_KEYBOARDTX].noautoenable = 1;
150
151	init_FIQ();
152}
153