diff options
Diffstat (limited to 'arch/m68k/atari')
-rw-r--r-- | arch/m68k/atari/ataints.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 3f41092d1b70..f699c829e594 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c | |||
@@ -122,6 +122,62 @@ static struct irq_chip atari_irq_chip = { | |||
122 | }; | 122 | }; |
123 | 123 | ||
124 | /* | 124 | /* |
125 | * ST-MFP timer D chained interrupts - each driver gets its own timer | ||
126 | * interrupt instance. | ||
127 | */ | ||
128 | |||
129 | struct mfptimerbase { | ||
130 | volatile struct MFP *mfp; | ||
131 | unsigned char mfp_mask, mfp_data; | ||
132 | unsigned short int_mask; | ||
133 | int handler_irq, mfptimer_irq, server_irq; | ||
134 | char *name; | ||
135 | } stmfp_base = { | ||
136 | .mfp = &st_mfp, | ||
137 | .int_mask = 0x0, | ||
138 | .handler_irq = IRQ_MFP_TIMD, | ||
139 | .mfptimer_irq = IRQ_MFP_TIMER1, | ||
140 | .name = "MFP Timer D" | ||
141 | }; | ||
142 | |||
143 | static irqreturn_t mfptimer_handler(int irq, void *dev_id) | ||
144 | { | ||
145 | struct mfptimerbase *base = dev_id; | ||
146 | int mach_irq; | ||
147 | unsigned char ints; | ||
148 | |||
149 | mach_irq = base->mfptimer_irq; | ||
150 | ints = base->int_mask; | ||
151 | for (; ints; mach_irq++, ints >>= 1) { | ||
152 | if (ints & 1) | ||
153 | generic_handle_irq(mach_irq); | ||
154 | } | ||
155 | return IRQ_HANDLED; | ||
156 | } | ||
157 | |||
158 | |||
159 | static void atari_mfptimer_enable(struct irq_data *data) | ||
160 | { | ||
161 | int mfp_num = data->irq - IRQ_MFP_TIMER1; | ||
162 | stmfp_base.int_mask |= 1 << mfp_num; | ||
163 | atari_enable_irq(IRQ_MFP_TIMD); | ||
164 | } | ||
165 | |||
166 | static void atari_mfptimer_disable(struct irq_data *data) | ||
167 | { | ||
168 | int mfp_num = data->irq - IRQ_MFP_TIMER1; | ||
169 | stmfp_base.int_mask &= ~(1 << mfp_num); | ||
170 | if (!stmfp_base.int_mask) | ||
171 | atari_disable_irq(IRQ_MFP_TIMD); | ||
172 | } | ||
173 | |||
174 | static struct irq_chip atari_mfptimer_chip = { | ||
175 | .name = "timer_d", | ||
176 | .irq_enable = atari_mfptimer_enable, | ||
177 | .irq_disable = atari_mfptimer_disable, | ||
178 | }; | ||
179 | |||
180 | /* | ||
125 | * void atari_init_IRQ (void) | 181 | * void atari_init_IRQ (void) |
126 | * | 182 | * |
127 | * Parameters: None | 183 | * Parameters: None |
@@ -198,6 +254,20 @@ void __init atari_init_IRQ(void) | |||
198 | /* Initialize the PSG: all sounds off, both ports output */ | 254 | /* Initialize the PSG: all sounds off, both ports output */ |
199 | sound_ym.rd_data_reg_sel = 7; | 255 | sound_ym.rd_data_reg_sel = 7; |
200 | sound_ym.wd_data = 0xff; | 256 | sound_ym.wd_data = 0xff; |
257 | |||
258 | m68k_setup_irq_controller(&atari_mfptimer_chip, handle_simple_irq, | ||
259 | IRQ_MFP_TIMER1, 8); | ||
260 | |||
261 | /* prepare timer D data for use as poll interrupt */ | ||
262 | /* set Timer D data Register - needs to be > 0 */ | ||
263 | st_mfp.tim_dt_d = 254; /* < 100 Hz */ | ||
264 | /* start timer D, div = 1:100 */ | ||
265 | st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x6; | ||
266 | |||
267 | /* request timer D dispatch handler */ | ||
268 | if (request_irq(IRQ_MFP_TIMD, mfptimer_handler, IRQF_SHARED, | ||
269 | stmfp_base.name, &stmfp_base)) | ||
270 | pr_err("Couldn't register %s interrupt\n", stmfp_base.name); | ||
201 | } | 271 | } |
202 | 272 | ||
203 | 273 | ||