Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6] / arch / sh / boards / saturn / irq.c
1 /*
2  * arch/sh/boards/saturn/irq.c
3  *
4  * Copyright (C) 2002 Paul Mundt
5  *
6  * Released under the terms of the GNU GPL v2.0.
7  */
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/interrupt.h>
11 #include <asm/irq.h>
12 #include <asm/io.h>
13
14 /*
15  * Interrupts map out as follows:
16  *
17  *  Vector      Name            Mask
18  *
19  *      64      VBLANKIN        0x0001
20  *      65      VBLANKOUT       0x0002
21  *      66      HBLANKIN        0x0004
22  *      67      TIMER0          0x0008
23  *      68      TIMER1          0x0010
24  *      69      DSPEND          0x0020
25  *      70      SOUNDREQUEST    0x0040
26  *      71      SYSTEMMANAGER   0x0080
27  *      72      PAD             0x0100
28  *      73      LEVEL2DMAEND    0x0200
29  *      74      LEVEL1DMAEND    0x0400
30  *      75      LEVEL0DMAEND    0x0800
31  *      76      DMAILLEGAL      0x1000
32  *      77      SRITEDRAWEND    0x2000
33  *      78      ABUS            0x8000
34  *
35  */
36 #define SATURN_IRQ_MIN          64      /* VBLANKIN */
37 #define SATURN_IRQ_MAX          78      /* ABUS */
38
39 #define SATURN_IRQ_MASK         0xbfff
40
41 static inline u32 saturn_irq_mask(unsigned int irq_nr)
42 {
43         u32 mask;
44
45         mask = (1 << (irq_nr - SATURN_IRQ_MIN));
46         mask <<= (irq_nr == SATURN_IRQ_MAX);
47         mask &= SATURN_IRQ_MASK;
48
49         return mask;
50 }
51
52 static inline void mask_saturn_irq(unsigned int irq_nr)
53 {
54         u32 mask;
55
56         mask = ctrl_inl(SATURN_IMR);
57         mask |= saturn_irq_mask(irq_nr);
58         ctrl_outl(mask, SATURN_IMR);
59 }
60
61 static inline void unmask_saturn_irq(unsigned int irq_nr)
62 {
63         u32 mask;
64
65         mask = ctrl_inl(SATURN_IMR);
66         mask &= ~saturn_irq_mask(irq_nr);
67         ctrl_outl(mask, SATURN_IMR);
68 }
69
70 static void disable_saturn_irq(unsigned int irq_nr)
71 {
72         mask_saturn_irq(irq_nr);
73 }
74
75 static void enable_saturn_irq(unsigned int irq_nr)
76 {
77         unmask_saturn_irq(irq_nr);
78 }
79
80 static void mask_and_ack_saturn_irq(unsigned int irq_nr)
81 {
82         mask_saturn_irq(irq_nr);
83 }
84
85 static void end_saturn_irq(unsigned int irq_nr)
86 {
87         if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
88                 unmask_saturn_irq(irq_nr);
89 }
90
91 static unsigned int startup_saturn_irq(unsigned int irq_nr)
92 {
93         unmask_saturn_irq(irq_nr);
94
95         return 0;
96 }
97
98 static void shutdown_saturn_irq(unsigned int irq_nr)
99 {
100         mask_saturn_irq(irq_nr);
101 }
102
103 static struct hw_interrupt_type saturn_int = {
104         .typename       = "Saturn",
105         .enable         = enable_saturn_irq,
106         .disable        = disable_saturn_irq,
107         .ack            = mask_and_ack_saturn_irq,
108         .end            = end_saturn_irq,
109         .startup        = startup_saturn_irq,
110         .shutdown       = shutdown_saturn_irq,
111 };
112
113 int saturn_irq_demux(int irq_nr)
114 {
115         /* FIXME */
116         return irq_nr;
117 }
118