1 /* -*- linux-c -*- */
2 /*
3  * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version
8  * 2 of the License, or (at your option) any later version.
9  *
10  **/
11 
12 /* Standard in kernel modules */
13 #include <linux/module.h>   /* Specifically, a module */
14 
15 #include <asm/io.h>
16 #include <linux/timer.h>
17 #include <linux/interrupt.h>
18 #include <linux/tty.h>
19 #include <linux/tty_flip.h>
20 #include <linux/mm.h>
21 #include <linux/version.h>
22 #include <asm/uaccess.h>
23 #include <linux/pci.h>
24 #include "8253xctl.h"
25 #include "8253xmcs.h"
26 
27 /*
28  * ----------------------------------------------------------------------
29  *
30  * Here starts the interrupt handling routines.  All of the following
31  * subroutines are declared as inline and are folded into
32  * sab8253x_interrupt().  They were separated out for readability's sake.
33  *
34  * Note: sab8253x_interrupt() is a "fast" interrupt, which means that it
35  * runs with interrupts turned off.  People who may want to modify
36  * sab8253x_interrupt() should try to keep the interrupt handler as fast as
37  * possible.  After you are done making modifications, it is not a bad
38  * idea to do:
39  *
40  * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
41  *
42  * and look at the resulting assemble code in serial.s.
43  *
44  * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
45  * -----------------------------------------------------------------------
46  */
47 
48 /* Note:  the inline interrupt routines constitute the smallest hardware
49    unit that must be examined when an interrupt comes up.  On the 4520
50    type cards, two ESCC2s must be examined.  Because the ESCC2s are in
51    a null terminated list the sab82532_interrupt also works for 2 port/1 port
52    single ESCC2 cards.
53 
54    On an 8520 type card there is but one ESCC8 thus the sab82538_interrupt
55    routine does not walk through a list.  But this requires some contortion
56    in dealing with the multichannel server.  The multichannel server has
57    at most 4 channel interface modules (CIM) 1/EB.  Each CIM has at most
58    two ESCC8s, thus the host card can have a list of 8 ESCC8s.  But by
59    walking the CIMs the exact ESCC8 that is interrupting can be identified.
60    Thus despite the complexity, really the MCS is a collection of 8520 type
61    cards multiplexed on one interrupt.  Thus after making some temporary
62    modifications of the board structure, the generic interrupt handler invokes
63    sab82538_interrupt handler just as for an 8520 type card.
64 */
65 
66 /* static forces inline compilation */
sab82532_interrupt(int irq,void * dev_id,struct pt_regs * regs)67 static void inline sab82532_interrupt(int irq, void *dev_id, struct pt_regs *regs)
68 {
69 	struct sab_port *port;
70 	struct sab_chip *chip=NULL;
71 	struct sab_board *bptr = (struct sab_board*) dev_id;
72 	union sab8253x_irq_status status;
73 	unsigned char gis;
74 
75 	for(chip = bptr->board_chipbase; chip != NULL; chip = chip->next_by_board)
76 	{
77 		port= chip->c_portbase;
78 		gis = READB(port, gis); /* Global! */
79 		status.stat=0;
80 
81 		/* Since the PORT interrupt are global,
82 		 * we do check all the ports for this chip
83 		 */
84 
85 		/* A 2 ports chip */
86 
87 		if(!(gis & SAB82532_GIS_MASK))
88 		{
89 			continue; /* no interrupt on this chip */
90 		}
91 
92 		if (gis & SAB82532_GIS_ISA0)
93 		{
94 			status.sreg.isr0 = READB(port, isr0);
95 		}
96 		else
97 		{
98 			status.sreg.isr0 = 0;
99 		}
100 		if (gis & SAB82532_GIS_ISA1)
101 		{
102 			status.sreg.isr1 = READB(port, isr1);
103 		}
104 		else
105 		{
106 			status.sreg.isr1 = 0;
107 		}
108 
109 		if (gis & SAB82532_GIS_PI)
110 		{
111 			status.sreg.pis = READB(port, pis);
112 		}
113 		else
114 		{
115 			status.sreg.pis = 0;
116 		}
117 
118 		if (status.stat)
119 		{
120 			if (status.images[ISR0_IDX] & port->receive_test)
121 			{
122 				(*port->receive_chars)(port, &status);	/* when the fifo is full */
123 				/* no time to schedule thread*/
124 			}
125 
126 			if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
127 			    (status.images[port->cts.irq] & port->cts.irqmask) ||
128 			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
129 			    (status.images[ISR1_IDX] & port->check_status_test))
130 			{
131 				(*port->check_status)(port, &status); /* this stuff should be */
132 				/* be moveable to scheduler */
133 				/* thread*/
134 			}
135 
136 			if (status.images[ISR1_IDX] & port->transmit_test)
137 			{
138 				(*port->transmit_chars)(port, &status); /* needs to be moved to task */
139 			}
140 		}
141 
142 		/* Get to next port on chip */
143 		port = port->next_by_chip;
144 		/* Port B */
145 		if (gis & SAB82532_GIS_ISB0)
146 		{
147 			status.images[ISR0_IDX] = READB(port, isr0);
148 		}
149 		else
150 		{
151 			status.images[ISR0_IDX] = 0;
152 		}
153 		if (gis & SAB82532_GIS_ISB1)
154 		{
155 			status.images[ISR1_IDX] = READB(port,isr1);
156 		}
157 		else
158 		{
159 			status.images[ISR1_IDX] = 0;
160 		}
161 		/* DO NOT SET PIS. IT was reset! */
162 
163 
164 		if (status.stat)
165 		{
166 			if (status.images[ISR0_IDX] & port->receive_test)
167 			{
168 				(*port->receive_chars)(port, &status);
169 			}
170 			if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
171 			    (status.images[port->cts.irq] & port->cts.irqmask) ||
172 			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
173 			    (status.images[ISR1_IDX] & port->check_status_test))
174 			{
175 				(*port->check_status)(port, &status);
176 			}
177 			if (status.images[ISR1_IDX] & port->transmit_test)
178 			{
179 				(*port->transmit_chars)(port, &status);
180 			}
181 		}
182 	}
183 }
184 
sab82538_interrupt(int irq,void * dev_id,struct pt_regs * regs)185 static void inline sab82538_interrupt(int irq, void *dev_id, struct pt_regs *regs)
186 {
187 	struct sab_port *port;
188 	struct sab_chip *chip=NULL;
189 	struct sab_board *bptr = (struct sab_board*) dev_id;
190 	union sab8253x_irq_status status;
191 	unsigned char gis,i;
192 
193 	chip = bptr->board_chipbase;
194 	port = chip->c_portbase;
195 
196 	gis = READB(port, gis); /* Global! */
197 	status.stat=0;
198 
199 	/* Since the PORT interrupt are global,
200 	 * we do check all the ports for this chip
201 	 */
202 
203 	/* 8 ports chip */
204 	if(!(gis & SAB82538_GIS_MASK))
205 	{
206 		return;
207 	}
208 
209 	if(gis & SAB82538_GIS_CII)
210 	{ /* A port interrupt! */
211 		/* Get the port */
212 		int portindex;
213 
214 		portindex = (gis & SAB82538_GIS_CHNL_MASK);
215 
216 		port = chip->c_portbase;
217 
218 		while(portindex)
219 		{
220 			port = port->next_by_chip;
221 			--portindex;
222 		}
223 
224 		status.images[ISR0_IDX] = READB(port,isr0);
225 		status.images[ISR1_IDX] = READB(port,isr1);
226 		if (gis & SAB82538_GIS_PIC)
227 		{
228 			status.images[PIS_IDX] =
229 				(*port->readbyte)(port,
230 						  ((unsigned char *)(port->regs)) +
231 						  SAB82538_REG_PIS_C);
232 		}
233 		else
234 		{
235 			status.images[PIS_IDX] = 0;
236 		}
237 
238 		if (status.stat)
239 		{
240 			if (status.images[ISR0_IDX] & port->receive_test)
241 			{
242 				(*port->receive_chars)(port, &status);
243 			}
244 			if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
245 			    (status.images[port->cts.irq] & port->cts.irqmask) ||
246 			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
247 			    (status.images[ISR1_IDX] & port->check_status_test))
248 			{
249 				(*port->check_status)(port, &status);
250 			}
251 			/*
252 			 * We know that with 8 ports chip, the bit corresponding to channel
253 			 * number is used in the parallel port... So we clear it
254 			 * Not too elegant!
255 			 */
256 			status.images[PIS_IDX] &= ~(1 << (gis&SAB82538_GIS_CHNL_MASK));
257 			if (status.images[ISR1_IDX] & port->transmit_test)
258 			{
259 				(*port->transmit_chars)(port, &status);
260 			}
261 		}
262 	}
263 
264 	/*
265 	 * Now we handle the "channel interrupt" case. The chip manual for the
266 	 * 8 ports chip states that "channel" and "port" interrupt are set
267 	 * independently so we still must check the parrallel port
268 	 *
269 	 * We should probably redesign the whole thing to be less AD HOC that we
270 	 * are now... We know that port C is used for DSR so we only check that one.
271 	 * PIS for port C was already recorded in  status.images[PIS_IDX], so we
272 	 * check the ports that are set
273 	 */
274 
275 	if (status.images[PIS_IDX])
276 	{
277 		for(i=0, port = chip->c_portbase;
278 		    i < chip->c_nports;
279 		    i++, port=port->next_by_chip)
280 		{
281 			if(status.images[PIS_IDX] & (0x1 << i))
282 			{ /* Match */
283 				/* Checking DSR */
284 				if(port->dsr.inverted)
285 				{
286 					port->dsr.val = (((*port->readbyte)
287 							  (port, port->dsr.reg) &
288 							  port->dsr.mask) ? 0 : 1);
289 				}
290 				else
291 				{
292 					port->dsr.val = ((*port->readbyte)(port, port->dsr.reg) &
293 							 port->dsr.mask);
294 				}
295 
296 				port->icount.dsr++;
297 				wake_up_interruptible(&port->delta_msr_wait); /* in case waiting on modem change */
298 			}
299 		}
300 	}
301 }
302 
303 /*
304  * This is the serial driver's generic interrupt routine
305  */
306 
sab8253x_interrupt(int irq,void * dev_id,struct pt_regs * regs)307 void sab8253x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
308 {
309 	extern SAB_BOARD *AuraBoardESCC2IrqRoot[];
310 	extern SAB_BOARD *AuraBoardESCC8IrqRoot[];
311 	extern SAB_BOARD *AuraBoardMCSIrqRoot[];
312 	AURA_CIM *cim;
313 	SAB_CHIP *chip;
314 	SAB_PORT *port;
315 	register SAB_BOARD *boardptr;
316 	register unsigned char intrmask;
317 	unsigned char stat;
318 	SAB_CHIP *save_chiplist;
319 	SAB_PORT *save_portlist;
320 
321 	if((irq < 0) || (irq >= NUMINTS))
322 	{
323 		printk(KERN_ALERT "sab8253x: bad interrupt value %i.\n", irq);
324 		return;
325 	}
326 	/* walk through all the cards on the interrupt that occurred. */
327 	for(boardptr = AuraBoardESCC2IrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
328 	{
329 		sab82532_interrupt(irq, boardptr, regs);
330 	}
331 
332 	for(boardptr = AuraBoardESCC8IrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
333 	{
334 		sab82538_interrupt(irq, boardptr, regs);
335 	}
336 
337 	for(boardptr = AuraBoardMCSIrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
338 	{
339 
340 		while(1)
341 		{
342 			writeb(0, (unsigned char*)(boardptr->CIMCMD_REG + CIMCMD_WRINTDIS)); /* prevent EBs from raising
343 											      * any more ints through the
344 											      * host card */
345 			stat = ~(unsigned char) /* active low !!!!! */
346 				readw((unsigned short*)
347 				      (((unsigned char*)boardptr->CIMCMD_REG) + CIMCMD_RDINT)); /* read out the ints */
348 				/* write to the MIC csr to reset the PCI interrupt */
349 			writeb(0, (unsigned char*)(boardptr->MICCMD_REG + MICCMD_MICCSR));
350 				/* reset the interrupt generation
351 				 * hardware on the host card*/
352 			/* now, write to the CIM interrupt ena to re-enable interrupt generation */
353 			writeb(0, (unsigned char*)(boardptr->CIMCMD_REG + CIMCMD_WRINTENA)); /* allow EBs to request ints
354 											      * through the host card */
355 			if(!stat)
356 			{
357 				break;
358 			}
359 			cim = boardptr->b_cimbase; /* cims in reverse order */
360 			for(intrmask = boardptr->b_intrmask;
361 			    intrmask != 0;
362 			    intrmask <<= 2, stat <<=2)
363 			{
364 				if(cim == NULL)
365 				{
366 					break;	/* no cim no ports */
367 				}
368 				if((intrmask & 0xc0) == 0) /* means no cim for these ints */
369 				{		/* cim not on list do not go to next */
370 					continue;
371 				}
372 				save_portlist = boardptr->board_portbase;
373 				save_chiplist = boardptr->board_chipbase;
374 				/* the goal is temporarily to make the structures
375 				 * look like 8x20 structures -- thus if I find
376 				 * a bug related to escc8s I need fix it in
377 				 * only one place. */
378 				switch(stat & 0xc0) /* possible ints */
379 				{
380 				default:
381 					break;
382 
383 				case 0x80:	/* esccB */
384 					chip = cim->ci_chipbase;
385 					if(!chip)
386 					{
387 						printk(KERN_ALERT "aura mcs: missing cim.\n");
388 						break;
389 					}
390 					chip = chip->next_by_cim;
391 					if(!chip)
392 					{
393 						printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
394 						break;
395 					}
396 					port = chip->c_portbase;
397 					boardptr->board_portbase = port;
398 					boardptr->board_chipbase = chip;
399 					sab82538_interrupt(irq, boardptr, regs);
400 					break;
401 
402 				case 0x40:	/* esccA */
403 					chip = cim->ci_chipbase;
404 					if(!chip)
405 					{
406 						printk(KERN_ALERT "aura mcs: missing cim.\n");
407 						break;
408 					}
409 					port = chip->c_portbase;
410 					boardptr->board_portbase = port;
411 					boardptr->board_chipbase = chip;
412 					sab82538_interrupt(irq, boardptr, regs);
413 					break;
414 
415 				case 0xc0:	/* esccB and esccA */
416 					chip = cim->ci_chipbase;
417 					if(!chip)
418 					{
419 						printk(KERN_ALERT "aura mcs: missing cim.\n");
420 						break;
421 					}
422 					port = chip->c_portbase;
423 					boardptr->board_portbase = port;
424 					boardptr->board_chipbase = chip;
425 					sab82538_interrupt(irq, boardptr, regs);
426 
427 					chip = cim->ci_chipbase;
428 					if(!chip)
429 					{
430 						printk(KERN_ALERT "aura mcs: missing cim.\n");
431 						break;
432 					}
433 					chip = chip->next_by_cim;
434 					if(!chip)
435 					{
436 						printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
437 						break;
438 					}
439 					port = chip->c_portbase;
440 					boardptr->board_portbase = port;
441 					boardptr->board_chipbase = chip;
442 					sab82538_interrupt(irq, boardptr, regs);
443 					break;
444 				}
445 				boardptr->board_portbase = save_portlist;
446 				boardptr->board_chipbase = save_chiplist;
447 				cim = cim->next_by_mcs;
448 			}
449 		}
450 	}
451 }
452 
453 /*
454  * -------------------------------------------------------------------
455  * Here ends the serial interrupt routines.
456  * -------------------------------------------------------------------
457  */
458 
459