1/*
2 *  linux/include/asm-arm/arch-arc/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 *   24-09-1996	RMK	Created
12 *   10-10-1996	RMK	Brought up to date with arch-sa110eval
13 *   22-10-1996	RMK	Changed interrupt numbers & uses new inb/outb macros
14 *   11-01-1998	RMK	Added mask_and_ack_irq
15 *   22-08-1998	RMK	Restructured IRQ routines
16 */
17#include <linux/config.h>
18#include <asm/hardware/ioc.h>
19#include <asm/io.h>
20
21#ifdef CONFIG_ARCH_ARC
22#define a_clf()	clf()
23#define a_stf()	stf()
24#else
25#define a_clf()	do { } while (0)
26#define a_stf()	do { } while (0)
27#endif
28
29#define fixup_irq(x) (x)
30
31static void arc_mask_irq_ack_a(unsigned int irq)
32{
33	unsigned int val, mask;
34
35	mask = 1 << irq;
36	a_clf();
37	val = ioc_readb(IOC_IRQMASKA);
38	ioc_writeb(val & ~mask, IOC_IRQMASKA);
39	ioc_writeb(mask, IOC_IRQCLRA);
40	a_stf();
41}
42
43static void arc_mask_irq_a(unsigned int irq)
44{
45	unsigned int val, mask;
46
47	mask = 1 << irq;
48	a_clf();
49	val = ioc_readb(IOC_IRQMASKA);
50	ioc_writeb(val & ~mask, IOC_IRQMASKA);
51	a_stf();
52}
53
54static void arc_unmask_irq_a(unsigned int irq)
55{
56	unsigned int val, mask;
57
58	mask = 1 << irq;
59	a_clf();
60	val = ioc_readb(IOC_IRQMASKA);
61	ioc_writeb(val | mask, IOC_IRQMASKA);
62	a_stf();
63}
64
65static void arc_mask_irq_b(unsigned int irq)
66{
67	unsigned int val, mask;
68
69	mask = 1 << (irq & 7);
70	val = ioc_readb(IOC_IRQMASKB);
71	ioc_writeb(val & ~mask, IOC_IRQMASKB);
72}
73
74static void arc_unmask_irq_b(unsigned int irq)
75{
76	unsigned int val, mask;
77
78	mask = 1 << (irq & 7);
79	val = ioc_readb(IOC_IRQMASKB);
80	ioc_writeb(val | mask, IOC_IRQMASKB);
81}
82
83static void arc_mask_irq_fiq(unsigned int irq)
84{
85	unsigned int val, mask;
86
87	mask = 1 << (irq & 7);
88	val = ioc_readb(IOC_FIQMASK);
89	ioc_writeb(val & ~mask, IOC_FIQMASK);
90}
91
92static void arc_unmask_irq_fiq(unsigned int irq)
93{
94	unsigned int val, mask;
95
96	mask = 1 << (irq & 7);
97	val = ioc_readb(IOC_FIQMASK);
98	ioc_writeb(val | mask, IOC_FIQMASK);
99}
100
101static __inline__ void irq_init_irq(void)
102{
103	int irq;
104
105	ioc_writeb(0, IOC_IRQMASKA);
106	ioc_writeb(0, IOC_IRQMASKB);
107	ioc_writeb(0, IOC_FIQMASK);
108
109	for (irq = 0; irq < NR_IRQS; irq++) {
110		switch (irq) {
111		case 0 ... 6:
112			irq_desc[irq].probe_ok = 1;
113			irq_desc[irq].valid    = 1;
114			irq_desc[irq].mask_ack = arc_mask_irq_ack_a;
115			irq_desc[irq].mask     = arc_mask_irq_a;
116			irq_desc[irq].unmask   = arc_unmask_irq_a;
117			break;
118
119		case 7:
120			irq_desc[irq].noautoenable = 1;
121			irq_desc[irq].valid    = 1;
122			irq_desc[irq].mask_ack = arc_mask_irq_ack_a;
123			irq_desc[irq].mask     = arc_mask_irq_a;
124			irq_desc[irq].unmask   = arc_unmask_irq_a;
125			break;
126
127		case 9 ... 15:
128			irq_desc[irq].probe_ok = 1;
129		case 8:
130			irq_desc[irq].valid    = 1;
131			irq_desc[irq].mask_ack = arc_mask_irq_b;
132			irq_desc[irq].mask     = arc_mask_irq_b;
133			irq_desc[irq].unmask   = arc_unmask_irq_b;
134			break;
135
136		case 64 ... 72:
137			irq_desc[irq].valid    = 1;
138			irq_desc[irq].mask_ack = arc_mask_irq_fiq;
139			irq_desc[irq].mask     = arc_mask_irq_fiq;
140			irq_desc[irq].unmask   = arc_unmask_irq_fiq;
141			break;
142		}
143	}
144
145	irq_desc[IRQ_KEYBOARDTX].noautoenable = 1;
146
147	init_FIQ();
148}
149