From: Dave A. <ai...@us...> - 2001-06-09 14:07:44
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/char In directory usw-pr-cvs1:/tmp/cvs-serv13105 Modified Files: dz.c dz.h Log Message: DA: changes to dz driver for VS3100 (won't work elsewhere).. I've never seen a chip with separate RX/TX interrupts before .. it seems to work for me ... for vs4000 you might need to change the vsbus int numbers until I write the vsbus autodetect IRQ code.. Index: dz.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/char/dz.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- dz.c 2001/02/26 02:28:27 1.4 +++ dz.c 2001/06/09 14:07:38 1.5 @@ -39,9 +39,11 @@ #include <linux/param.h> #include <linux/tqueue.h> #include <linux/interrupt.h> - +#include <linux/delay.h> #ifdef CONFIG_VAX -#define SERIAL 0 /* FIXME: this is wrong */ +#define SERIAL_RX 0xB0 /* FIXME: this is wrong */ +#define SERIAL_TX 0xB1 /* FIXME: this is wrong */ +#define SERIAL SERIAL_RX #else #include <asm-mips/wbflush.h> /* for definition of SERIAL */ @@ -328,8 +330,6 @@ { unsigned char tmp; - - if (info->x_char) { /* XON/XOFF chars */ dz_out (info, DZ_TDR, info->x_char); info->icount.tx++; @@ -385,7 +385,9 @@ * It deals with the multiple ports. * ------------------------------------------------------------ */ -static void dz_interrupt (int irq, void *dev, struct pt_regs *regs) +/* VAX has separate RX/TX interrupts */ +#ifdef CONFIG_VAX +static void dz_interrupt_rx (int irq, void *dev, struct pt_regs *regs) { struct dz_serial *info; unsigned short status; @@ -396,10 +398,40 @@ if (status & DZ_RDONE) receive_chars (info); /* the receive function */ + vsbus_clear_int(7); + +} + +static void dz_interrupt_tx (int irq, void *dev, struct pt_regs *regs) +{ + struct dz_serial *info; + unsigned short status; + + status = dz_in ((struct dz_serial *)dev, DZ_CSR); /* get the reason why we just got an irq */ + info = lines[LINE(status)]; /* re-arrange info the proper port */ + if (status & DZ_TRDY) transmit_chars (info); + + vsbus_clear_int(6); + } +#else +static void dz_interrupt (int irq, void *dev, struct pt_regs *regs) +{ + struct dz_serial *info; + unsigned short status; + status = dz_in ((struct dz_serial *)dev, DZ_CSR); /* get the reason why we just got an irq */ + info = lines[LINE(status)]; /* re-arrange info the proper port */ + + if (status & DZ_RDONE) + receive_chars (info); /* the receive function */ + + if (status & DZ_TRDY) + transmit_chars (info); +} +#endif /* * ------------------------------------------------------------------- * Here ends the DZ interrupt routines. @@ -493,6 +525,10 @@ tmp |= (DZ_RIE | DZ_TIE | DZ_MSE); dz_out (info, DZ_CSR, tmp); +#ifdef CONFIG_VAX + vsbus_enable_int(6); + vsbus_enable_int(7); +#endif info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; /* set up the speed */ @@ -674,7 +710,6 @@ if (from_user) { - down (&tmp_buf_sem); while (1) { c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); @@ -1265,7 +1300,7 @@ if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE)) return -ENODEV; - + printk("dz opening line %d\n",line); info = lines[line]; info->count++; @@ -1279,8 +1314,6 @@ if (retval) return retval; - - retval = block_til_ready (tty, filp, info); if (retval) return retval; @@ -1296,6 +1329,7 @@ info->session = current->session; info->pgrp = current->pgrp; + return 0; } @@ -1309,7 +1343,7 @@ { int i, flags; struct dz_serial *info; - + int irq; /* Setup base handler, and timer table. */ init_bh (SERIAL_BH, do_serial_bh); @@ -1370,14 +1404,14 @@ info->magic = SERIAL_MAGIC; #ifdef CONFIG_VAX - info->port = (unsigned long) 0x200A0000; + info->port = (unsigned long) dz11_addr; #else if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) info->port = (unsigned long) KN01_DZ11_BASE; else info->port = (unsigned long) KN02_DZ11_BASE; #endif - + info->line = i; info->tty = 0; info->close_delay = 50; @@ -1399,10 +1433,12 @@ set up in setup.c to handle this. */ if (! info->port) return 0; - - printk("ttyS%02d at 0x%04x (irq = %d)\n", info->line, info->port, SERIAL); +#ifdef CONFIG_VAX + printk("ttyS%d at 0x%04x (irq = %d, %d)\n", info->line, info->port, SERIAL_RX, SERIAL_TX); +#else + printk("ttyS%d at 0x%04x (irq = %d)\n", info->line, info->port, SERIAL); +#endif } - /* reset the chip */ #ifndef CONFIG_SERIAL_CONSOLE dz_out(info, DZ_CSR, DZ_CLR); @@ -1416,21 +1452,48 @@ /* order matters here... the trick is that flags is updated... in request_irq - to immediatedly obliterate it is unwise. */ - restore_flags(flags); - + restore_flags(flags); +#if 0 + { + short i; - if (request_irq (SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0])) + + autoirq_setup(0); + vsbus_enable_int(6); + i = dz_in(info, DZ_TCR); + dz_out(info, DZ_CSR, DZ_MSE|DZ_TIE); + dz_out(info, DZ_TCR, 0); + udelay(100); + dz_out(info, DZ_TCR, 1); + udelay(10000); + dz_out(info, DZ_TCR, 1); + vsbus_clear_int(6); + irq=autoirq_report(100); + } + printk("going for IRQ %d\n", irq); +#endif +#ifdef CONFIG_VAX + if (request_irq (SERIAL_TX, dz_interrupt_tx, SA_INTERRUPT, "DZ", lines[0])) panic ("Unable to register DZ interrupt\n"); - + if (request_irq (SERIAL_RX, dz_interrupt_rx, SA_INTERRUPT, "DZ", lines[0])) + panic ("Unable to register DZ interrupt\n"); +#else + if (request_irq (SERIAL, dz_interrupt_rx, SA_INTERRUPT, "DZ", lines[0])) + panic ("Unable to register DZ interrupt\n"); +#endif + return 0; } +__initcall(dz_init); + #ifdef CONFIG_SERIAL_CONSOLE static void dz_console_put_char (unsigned char ch) { unsigned long flags; int loops = 2500; unsigned short tmp = ch; + unsigned short tcr, mask; /* this code sends stuff out to serial device - spinning its wheels and waiting. */ @@ -1440,7 +1503,9 @@ save_flags(flags); cli(); - + mask = 1 << dz_console->line; + tcr = dz_in (dz_console, DZ_TCR); /* read the TX flag */ + dz_out(dz_console, DZ_TCR, mask); /* spin our wheels */ while (((dz_in(dz_console,DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--) ; @@ -1448,6 +1513,7 @@ /* Actually transmit the character. */ dz_out (dz_console, DZ_TDR, tmp); + dz_out(dz_console, DZ_TCR, tcr); restore_flags(flags); } /* Index: dz.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/char/dz.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- dz.h 2001/01/26 00:27:00 1.2 +++ dz.h 2001/06/09 14:07:38 1.3 @@ -116,7 +116,11 @@ #define DZ_TDR 0x18 /* Transmit Data Register */ #endif +#ifdef CONFIG_VAX #define DZ_NB_PORT 4 +#else +#define DZ_NB_PORT 4 +#endif #define DZ_XMIT_SIZE 4096 /* buffer size */ #define WAKEUP_CHARS DZ_XMIT_SIZE/4 @@ -213,7 +217,12 @@ static void dz_stop (struct tty_struct *); static void dz_start (struct tty_struct *); +#ifdef CONFIG_VAX +static void dz_interrupt_rx (int, void *, struct pt_regs *); +static void dz_interrupt_tx (int, void *, struct pt_regs *); +#else static void dz_interrupt (int, void *, struct pt_regs *); +#endif static void do_serial_bh (void); static void do_softint (void *); static void do_serial_hangup (void *); |