~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/m68k/atari/ataints.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * arch/m68k/atari/ataints.c -- Atari Linux interrupt handling code
 
3
 *
 
4
 * 5/2/94 Roman Hodek:
 
5
 *  Added support for TT interrupts; setup for TT SCU (may someone has
 
6
 *  twiddled there and we won't get the right interrupts :-()
 
7
 *
 
8
 *  Major change: The device-independent code in m68k/ints.c didn't know
 
9
 *  about non-autovec ints yet. It hardcoded the number of possible ints to
 
10
 *  7 (IRQ1...IRQ7). But the Atari has lots of non-autovec ints! I made the
 
11
 *  number of possible ints a constant defined in interrupt.h, which is
 
12
 *  47 for the Atari. So we can call request_irq() for all Atari interrupts
 
13
 *  just the normal way. Additionally, all vectors >= 48 are initialized to
 
14
 *  call trap() instead of inthandler(). This must be changed here, too.
 
15
 *
 
16
 * 1995-07-16 Lars Brinkhoff <f93labr@dd.chalmers.se>:
 
17
 *  Corrected a bug in atari_add_isr() which rejected all SCC
 
18
 *  interrupt sources if there were no TT MFP!
 
19
 *
 
20
 * 12/13/95: New interface functions atari_level_triggered_int() and
 
21
 *  atari_register_vme_int() as support for level triggered VME interrupts.
 
22
 *
 
23
 * 02/12/96: (Roman)
 
24
 *  Total rewrite of Atari interrupt handling, for new scheme see comments
 
25
 *  below.
 
26
 *
 
27
 * 1996-09-03 lars brinkhoff <f93labr@dd.chalmers.se>:
 
28
 *  Added new function atari_unregister_vme_int(), and
 
29
 *  modified atari_register_vme_int() as well as IS_VALID_INTNO()
 
30
 *  to work with it.
 
31
 *
 
32
 * This file is subject to the terms and conditions of the GNU General Public
 
33
 * License.  See the file COPYING in the main directory of this archive
 
34
 * for more details.
 
35
 *
 
36
 */
 
37
 
 
38
#include <linux/types.h>
 
39
#include <linux/kernel.h>
 
40
#include <linux/kernel_stat.h>
 
41
#include <linux/init.h>
 
42
#include <linux/seq_file.h>
 
43
#include <linux/module.h>
 
44
 
 
45
#include <asm/system.h>
 
46
#include <asm/traps.h>
 
47
 
 
48
#include <asm/atarihw.h>
 
49
#include <asm/atariints.h>
 
50
#include <asm/atari_stdma.h>
 
51
#include <asm/irq.h>
 
52
#include <asm/entry.h>
 
53
 
 
54
 
 
55
/*
 
56
 * Atari interrupt handling scheme:
 
57
 * --------------------------------
 
58
 *
 
59
 * All interrupt source have an internal number (defined in
 
60
 * <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP,
 
61
 * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can
 
62
 * be allocated by atari_register_vme_int().
 
63
 */
 
64
 
 
65
/*
 
66
 * Bitmap for free interrupt vector numbers
 
67
 * (new vectors starting from 0x70 can be allocated by
 
68
 * atari_register_vme_int())
 
69
 */
 
70
static int free_vme_vec_bitmap;
 
71
 
 
72
/* GK:
 
73
 * HBL IRQ handler for Falcon. Nobody needs it :-)
 
74
 * ++andreas: raise ipl to disable further HBLANK interrupts.
 
75
 */
 
76
asmlinkage void falcon_hblhandler(void);
 
77
asm(".text\n"
 
78
__ALIGN_STR "\n\t"
 
79
"falcon_hblhandler:\n\t"
 
80
        "orw    #0x200,%sp@\n\t"        /* set saved ipl to 2 */
 
81
        "rte");
 
82
 
 
83
extern void atari_microwire_cmd(int cmd);
 
84
 
 
85
extern int atari_SCC_reset_done;
 
86
 
 
87
static unsigned int atari_irq_startup(struct irq_data *data)
 
88
{
 
89
        unsigned int irq = data->irq;
 
90
 
 
91
        m68k_irq_startup(data);
 
92
        atari_turnon_irq(irq);
 
93
        atari_enable_irq(irq);
 
94
        return 0;
 
95
}
 
96
 
 
97
static void atari_irq_shutdown(struct irq_data *data)
 
98
{
 
99
        unsigned int irq = data->irq;
 
100
 
 
101
        atari_disable_irq(irq);
 
102
        atari_turnoff_irq(irq);
 
103
        m68k_irq_shutdown(data);
 
104
 
 
105
        if (irq == IRQ_AUTO_4)
 
106
            vectors[VEC_INT4] = falcon_hblhandler;
 
107
}
 
108
 
 
109
static void atari_irq_enable(struct irq_data *data)
 
110
{
 
111
        atari_enable_irq(data->irq);
 
112
}
 
113
 
 
114
static void atari_irq_disable(struct irq_data *data)
 
115
{
 
116
        atari_disable_irq(data->irq);
 
117
}
 
118
 
 
119
static struct irq_chip atari_irq_chip = {
 
120
        .name           = "atari",
 
121
        .irq_startup    = atari_irq_startup,
 
122
        .irq_shutdown   = atari_irq_shutdown,
 
123
        .irq_enable     = atari_irq_enable,
 
124
        .irq_disable    = atari_irq_disable,
 
125
};
 
126
 
 
127
/*
 
128
 * void atari_init_IRQ (void)
 
129
 *
 
130
 * Parameters:  None
 
131
 *
 
132
 * Returns:     Nothing
 
133
 *
 
134
 * This function should be called during kernel startup to initialize
 
135
 * the atari IRQ handling routines.
 
136
 */
 
137
 
 
138
void __init atari_init_IRQ(void)
 
139
{
 
140
        m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER);
 
141
        m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1,
 
142
                                  NUM_ATARI_SOURCES - 1);
 
143
 
 
144
        /* Initialize the MFP(s) */
 
145
 
 
146
#ifdef ATARI_USE_SOFTWARE_EOI
 
147
        st_mfp.vec_adr  = 0x48; /* Software EOI-Mode */
 
148
#else
 
149
        st_mfp.vec_adr  = 0x40; /* Automatic EOI-Mode */
 
150
#endif
 
151
        st_mfp.int_en_a = 0x00; /* turn off MFP-Ints */
 
152
        st_mfp.int_en_b = 0x00;
 
153
        st_mfp.int_mk_a = 0xff; /* no Masking */
 
154
        st_mfp.int_mk_b = 0xff;
 
155
 
 
156
        if (ATARIHW_PRESENT(TT_MFP)) {
 
157
#ifdef ATARI_USE_SOFTWARE_EOI
 
158
                tt_mfp.vec_adr  = 0x58;         /* Software EOI-Mode */
 
159
#else
 
160
                tt_mfp.vec_adr  = 0x50;         /* Automatic EOI-Mode */
 
161
#endif
 
162
                tt_mfp.int_en_a = 0x00;         /* turn off MFP-Ints */
 
163
                tt_mfp.int_en_b = 0x00;
 
164
                tt_mfp.int_mk_a = 0xff;         /* no Masking */
 
165
                tt_mfp.int_mk_b = 0xff;
 
166
        }
 
167
 
 
168
        if (ATARIHW_PRESENT(SCC) && !atari_SCC_reset_done) {
 
169
                atari_scc.cha_a_ctrl = 9;
 
170
                MFPDELAY();
 
171
                atari_scc.cha_a_ctrl = (char) 0xc0; /* hardware reset */
 
172
        }
 
173
 
 
174
        if (ATARIHW_PRESENT(SCU)) {
 
175
                /* init the SCU if present */
 
176
                tt_scu.sys_mask = 0x10;         /* enable VBL (for the cursor) and
 
177
                                                                         * disable HSYNC interrupts (who
 
178
                                                                         * needs them?)  MFP and SCC are
 
179
                                                                         * enabled in VME mask
 
180
                                                                         */
 
181
                tt_scu.vme_mask = 0x60;         /* enable MFP and SCC ints */
 
182
        } else {
 
183
                /* If no SCU and no Hades, the HSYNC interrupt needs to be
 
184
                 * disabled this way. (Else _inthandler in kernel/sys_call.S
 
185
                 * gets overruns)
 
186
                 */
 
187
 
 
188
                vectors[VEC_INT2] = falcon_hblhandler;
 
189
                vectors[VEC_INT4] = falcon_hblhandler;
 
190
        }
 
191
 
 
192
        if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) {
 
193
                /* Initialize the LM1992 Sound Controller to enable
 
194
                   the PSG sound.  This is misplaced here, it should
 
195
                   be in an atasound_init(), that doesn't exist yet. */
 
196
                atari_microwire_cmd(MW_LM1992_PSG_HIGH);
 
197
        }
 
198
 
 
199
        stdma_init();
 
200
 
 
201
        /* Initialize the PSG: all sounds off, both ports output */
 
202
        sound_ym.rd_data_reg_sel = 7;
 
203
        sound_ym.wd_data = 0xff;
 
204
}
 
205
 
 
206
 
 
207
/*
 
208
 * atari_register_vme_int() returns the number of a free interrupt vector for
 
209
 * hardware with a programmable int vector (probably a VME board).
 
210
 */
 
211
 
 
212
unsigned long atari_register_vme_int(void)
 
213
{
 
214
        int i;
 
215
 
 
216
        for (i = 0; i < 32; i++)
 
217
                if ((free_vme_vec_bitmap & (1 << i)) == 0)
 
218
                        break;
 
219
 
 
220
        if (i == 16)
 
221
                return 0;
 
222
 
 
223
        free_vme_vec_bitmap |= 1 << i;
 
224
        return VME_SOURCE_BASE + i;
 
225
}
 
226
EXPORT_SYMBOL(atari_register_vme_int);
 
227
 
 
228
 
 
229
void atari_unregister_vme_int(unsigned long irq)
 
230
{
 
231
        if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
 
232
                irq -= VME_SOURCE_BASE;
 
233
                free_vme_vec_bitmap &= ~(1 << irq);
 
234
        }
 
235
}
 
236
EXPORT_SYMBOL(atari_unregister_vme_int);
 
237
 
 
238