[SERIAL PATCH] 2.5.45 serial updates

From: Russell King (rmk@arm.linux.org.uk)
Date: Sat Nov 02 2002 - 12:02:28 EST


Here's some serial updates that're heading in Linus direction shortly.
Everything should work as before; this is mostly just cleanups and a
couple of bug fixes.

When people report problems with the 8250 autoconfiguration stuff,
please enable the autoconfig debug in 8250.c and send the resulting
messages for that port - I'm not expecting problems, but this
information will be crucial to finding any problem in this area.

<rmk@flint.arm.linux.org.uk> (02/11/02 1.881)
  [SERIAL] Set port->type to unknown only when using autoconfig

<rmk@flint.arm.linux.org.uk> (02/11/02 1.880)
  [SERIAL] Fix build errors and warnings
  - Remove last usage of EVT_WRITE_WAKEUP
  - Remove unused label + kfree()
  - scratch3 now known as id3

<rmk@flint.arm.linux.org.uk> (02/11/02 1.879)
  [SERIAL] Tidy up 8250 port type detection
  The original port detection code was one large function with many
  tests without any clear structure.
        
  This cset cleans this up, splitting out the tests for 8250/16450
  vs 16550 vs 16550A vs later ports, and adds comments about why
  we test what we're testing.

<rmk@flint.arm.linux.org.uk> (02/11/02 1.878)
  [SERIAL] Make ALPHA_KLUDGE_MCR more generic for bluetooth modems, etc
  In addition to the Alpha OUT1/OUT2 kludge, devices like Bluetooth
  modems connected to serial ports make use of the modem control lines
  in non-standard ways. Therefore, we implement a more flexible way to
  allow the modem control outputs to be forced to particular values
  irrespective of the normal usage of these signals.

<rmk@flint.arm.linux.org.uk> (02/11/02 1.877)
  [SERIAL] Fix up formatting of serial names
  The tty layer's tty_name requires formatting codes in driver->name
  for the devfs and non-devfs cases.

<rmk@flint.arm.linux.org.uk> (02/11/02 1.876)
  [SERIAL] Fix up 8250 IRQ chain handling
  - Unlink port from chain if request_irq fails
  - Allow port to define whether we use shared IRQs
    (this is required for PCMCIA serial cards where the serial
     card shares the same IRQ as the socket status IRQ.)
  - Convert remaining ASYNC_ flags to UPF_ flags

<rmk@flint.arm.linux.org.uk> (02/11/02 1.875)
  [SERIAL] Fix two incorrect uses of __FUNCTION__

<rmk@flint.arm.linux.org.uk> (02/11/02 1.874)
  [SERIAL] Remove struct pci_board from init_fn
  Traditionally, we allocated the private array of port parameters based on
  the detected board->num_ports, and then called the init_fn with the board
  pointer (which points into the global table.) Some init_fn implementations
  modify num_ports, which therefore affects the global table. Unfortunately,
  this means that if the init_fn increases num_ports (because we have two
  almost identical cards, the first with a smaller number of ports than the
  second), we will overwrite memory which hasn't been allocated to us.
        
  This cset no longer passes the board pointer into the init_fn, but instead
  allows the init_fn to return the number of ports found, or zero to use the
  default value in board->num_ports, or negative error number.

<rmk@flint.arm.linux.org.uk> (02/11/02 1.873)
  [SERIAL] Rename uart_event() to uart_write_wakeup()
  uart_event() only has one purpose, which is to wake up any pending
  writers via the line discipline. Rename it to reflect its real
  functionality, and drop EVT_WRITE_WAKEUP.

diff -Nru a/drivers/serial/21285.c b/drivers/serial/21285.c
--- a/drivers/serial/21285.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/21285.c Sat Nov 2 16:55:01 2002
@@ -171,7 +171,7 @@
         } while (--count > 0 && !(*CSR_UARTFLG & 0x20));
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(port);
 
         if (uart_circ_empty(xmit))
                 serial21285_stop_tx(port, 0);
@@ -485,11 +485,7 @@
 static struct uart_driver serial21285_reg = {
         .owner = THIS_MODULE,
         .driver_name = "ttyFB",
-#ifdef CONFIG_DEVFS_FS
         .dev_name = "ttyFB%d",
-#else
- .dev_name = "ttyFB",
-#endif
         .major = SERIAL_21285_MAJOR,
         .minor = SERIAL_21285_MINOR,
         .nr = 1,
diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c
--- a/drivers/serial/8250.c Sat Nov 2 16:55:00 2002
+++ b/drivers/serial/8250.c Sat Nov 2 16:55:00 2002
@@ -124,6 +124,8 @@
         unsigned char ier;
         unsigned char rev;
         unsigned char lcr;
+ unsigned char mcr_mask; /* mask of user bits */
+ unsigned char mcr_force; /* mask of forced bits */
         unsigned int lsr_break_flag;
 
         /*
@@ -342,10 +344,9 @@
  *
  * What evil have men's minds wrought...
  */
-static void
-autoconfig_startech_uarts(struct uart_8250_port *up)
+static void autoconfig_has_efr(struct uart_8250_port *up)
 {
- unsigned char scratch, scratch2, scratch3, scratch4;
+ unsigned char id1, id2, id3, rev, saved_dll, saved_dlm;
 
         /*
          * First we check to see if it's an Oxford Semiconductor UART.
@@ -354,31 +355,32 @@
          * Semiconductor clone chips lock up if you try writing to the
          * LSR register (which serial_icr_read does)
          */
- if (up->port.type == PORT_16550A) {
- /*
- * EFR [4] must be set else this test fails
- *
- * This shouldn't be necessary, but Mike Hudson
- * (Exoray@isys.ca) claims that it's needed for 952
- * dual UART's (which are not recommended for new designs).
- */
- up->acr = 0;
- serial_out(up, UART_LCR, 0xBF);
- serial_out(up, UART_EFR, 0x10);
- serial_out(up, UART_LCR, 0x00);
- /* Check for Oxford Semiconductor 16C950 */
- scratch = serial_icr_read(up, UART_ID1);
- scratch2 = serial_icr_read(up, UART_ID2);
- scratch3 = serial_icr_read(up, UART_ID3);
-
- if (scratch == 0x16 && scratch2 == 0xC9 &&
- (scratch3 == 0x50 || scratch3 == 0x52 ||
- scratch3 == 0x54)) {
- up->port.type = PORT_16C950;
- up->rev = serial_icr_read(up, UART_REV) |
- (scratch3 << 8);
- return;
- }
+
+ /*
+ * Check for Oxford Semiconductor 16C950.
+ *
+ * EFR [4] must be set else this test fails.
+ *
+ * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
+ * claims that it's needed for 952 dual UART's (which are not
+ * recommended for new designs).
+ */
+ up->acr = 0;
+ serial_out(up, UART_LCR, 0xBF);
+ serial_out(up, UART_EFR, UART_EFR_ECB);
+ serial_out(up, UART_LCR, 0x00);
+ id1 = serial_icr_read(up, UART_ID1);
+ id2 = serial_icr_read(up, UART_ID2);
+ id3 = serial_icr_read(up, UART_ID3);
+ rev = serial_icr_read(up, UART_REV);
+
+ DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
+
+ if (id1 == 0x16 && id2 == 0xC9 &&
+ (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
+ up->port.type = PORT_16C950;
+ up->rev = rev | (id3 << 8);
+ return;
         }
         
         /*
@@ -389,34 +391,28 @@
          * 0x12 - XR16C2850.
          * 0x14 - XR16C854.
          */
-
- /* Save the DLL and DLM */
-
         serial_outp(up, UART_LCR, UART_LCR_DLAB);
- scratch3 = serial_inp(up, UART_DLL);
- scratch4 = serial_inp(up, UART_DLM);
-
+ saved_dll = serial_inp(up, UART_DLL);
+ saved_dlm = serial_inp(up, UART_DLM);
         serial_outp(up, UART_DLL, 0);
         serial_outp(up, UART_DLM, 0);
- scratch2 = serial_inp(up, UART_DLL);
- scratch = serial_inp(up, UART_DLM);
- serial_outp(up, UART_LCR, 0);
-
- if (scratch == 0x10 || scratch == 0x12 || scratch == 0x14) {
- if (scratch == 0x10)
- up->rev = scratch2;
+ id2 = serial_inp(up, UART_DLL);
+ id1 = serial_inp(up, UART_DLM);
+ serial_outp(up, UART_DLL, saved_dll);
+ serial_outp(up, UART_DLM, saved_dlm);
+
+ DEBUG_AUTOCONF("850id=%02x:%02x ", id1, id2);
+
+ if (id1 == 0x10 || id1 == 0x12 || id1 == 0x14) {
+ if (id1 == 0x10)
+ up->rev = id2;
                 up->port.type = PORT_16850;
                 return;
         }
 
- /* Restore the DLL and DLM */
-
- serial_outp(up, UART_LCR, UART_LCR_DLAB);
- serial_outp(up, UART_DLL, scratch3);
- serial_outp(up, UART_DLM, scratch4);
- serial_outp(up, UART_LCR, 0);
-
         /*
+ * It wasn't an XR16C850.
+ *
          * We distinguish between the '654 and the '650 by counting
          * how many bytes are in the FIFO. I'm using this for now,
          * since that's the technique that was sent to me in the
@@ -430,6 +426,85 @@
 }
 
 /*
+ * We detected a chip without a FIFO. Only two fall into
+ * this category - the original 8250 and the 16450. The
+ * 16450 has a scratch register (accessible with LCR=0)
+ */
+static void autoconfig_8250(struct uart_8250_port *up)
+{
+ unsigned char scratch, status1, status2;
+
+ up->port.type = PORT_8250;
+
+ scratch = serial_in(up, UART_SCR);
+ serial_outp(up, UART_SCR, 0xa5);
+ status1 = serial_in(up, UART_SCR);
+ serial_outp(up, UART_SCR, 0x5a);
+ status2 = serial_in(up, UART_SCR);
+ serial_outp(up, UART_SCR, scratch);
+
+ if (status1 == 0xa5 && status2 == 0x5a)
+ up->port.type = PORT_16450;
+}
+
+/*
+ * We know that the chip has FIFOs. Does it have an EFR? The
+ * EFR is located in the same register position as the IIR and
+ * we know the top two bits of the IIR are currently set. The
+ * EFR should contain zero. Try to read the EFR.
+ */
+static void autoconfig_16550a(struct uart_8250_port *up)
+{
+ unsigned char status1, status2;
+
+ up->port.type = PORT_16550A;
+
+ /*
+ * Check for presence of the EFR when DLAB is set.
+ * Only ST16C650V1 UARTs pass this test.
+ */
+ serial_outp(up, UART_LCR, UART_LCR_DLAB);
+ if (serial_in(up, UART_EFR) == 0) {
+ DEBUG_AUTOCONF("EFRv1 ");
+ up->port.type = PORT_16650;
+ return;
+ }
+
+ /*
+ * Maybe it requires 0xbf to be written to the LCR.
+ * (other ST16C650V2 UARTs, TI16C752A, etc)
+ */
+ serial_outp(up, UART_LCR, 0xBF);
+ if (serial_in(up, UART_EFR) == 0) {
+ DEBUG_AUTOCONF("EFRv2 ");
+ autoconfig_has_efr(up);
+ return;
+ }
+
+ /*
+ * No EFR. Try to detect a TI16750, which only sets bit 5 of
+ * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
+ * Try setting it with and without DLAB set. Cheap clones
+ * set bit 5 without DLAB set.
+ */
+ serial_outp(up, UART_LCR, 0);
+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+ status1 = serial_in(up, UART_IIR) >> 5;
+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ serial_outp(up, UART_LCR, UART_LCR_DLAB);
+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+ status2 = serial_in(up, UART_IIR) >> 5;
+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+
+ DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
+
+ if (status1 == 6 && status2 == 7) {
+ up->port.type = PORT_16750;
+ return;
+ }
+}
+
+/*
  * This routine is called by rs_init() to initialize a specific serial
  * port. It determines what type of UART chip this serial port is
  * using: 8250, 16450, 16550, 16550A. The important question is
@@ -438,16 +513,16 @@
  */
 static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
 {
- unsigned char status1, status2, scratch, scratch2, scratch3;
+ unsigned char status1, scratch, scratch2, scratch3;
         unsigned char save_lcr, save_mcr;
         unsigned long flags;
 
- DEBUG_AUTOCONF("Testing ttyS%d (0x%04x, 0x%08lx)...\n",
- up->port.line, up->port.iobase, up->port.membase);
-
         if (!up->port.iobase && !up->port.membase)
                 return;
 
+ DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%08lx): ",
+ up->port.line, up->port.iobase, up->port.membase);
+
         /*
          * We really do need global IRQs disabled here - we're going to
          * be frobbing the chips IRQ enable register to see if it exists.
@@ -455,7 +530,7 @@
         spin_lock_irqsave(&up->port.lock, flags);
 // save_flags(flags); cli();
 
- if (!(up->port.flags & ASYNC_BUGGY_UART)) {
+ if (!(up->port.flags & UPF_BUGGY_UART)) {
                 /*
                  * Do a simple existence test first; if we fail this,
                  * there's no point trying anything else.
@@ -465,6 +540,9 @@
                  * assumption is that 0x80 is a non-existent port;
                  * which should be safe since include/asm/io.h also
                  * makes this assumption.
+ *
+ * Note: this is safe as long as MCR bit 4 is clear
+ * and the device is in "PC" mode.
                  */
                 scratch = serial_inp(up, UART_IER);
                 serial_outp(up, UART_IER, 0);
@@ -482,9 +560,8 @@
                         /*
                          * We failed; there's nothing here
                          */
- DEBUG_AUTOCONF("serial: ttyS%d: simple autoconfig "
- "failed (%02x, %02x)\n",
- up->port.line, scratch2, scratch3);
+ DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
+ scratch2, scratch3);
                         goto out;
                 }
         }
@@ -501,69 +578,50 @@
          * manufacturer would be stupid enough to design a board
          * that conflicts with COM 1-4 --- we hope!
          */
- if (!(up->port.flags & ASYNC_SKIP_TEST)) {
+ if (!(up->port.flags & UPF_SKIP_TEST)) {
                 serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
                 status1 = serial_inp(up, UART_MSR) & 0xF0;
                 serial_outp(up, UART_MCR, save_mcr);
                 if (status1 != 0x90) {
- DEBUG_AUTOCONF("serial: ttyS%d: no UART loopback "
- "failed\n", up->port.line);
+ DEBUG_AUTOCONF("LOOP test failed (%02x) ",
+ status1);
                         goto out;
                 }
         }
- serial_outp(up, UART_LCR, 0xBF); /* set up for StarTech test */
- serial_outp(up, UART_EFR, 0); /* EFR is the same as FCR */
+
+ /*
+ * We're pretty sure there's a port here. Lets find out what
+ * type of port it is. The IIR top two bits allows us to find
+ * out if its 8250 or 16450, 16550, 16550A or later. This
+ * determines what we test for next.
+ *
+ * We also initialise the EFR (if any) to zero for later. The
+ * EFR occupies the same register location as the FCR and IIR.
+ */
+ serial_outp(up, UART_LCR, 0xBF);
+ serial_outp(up, UART_EFR, 0);
         serial_outp(up, UART_LCR, 0);
+
         serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
         scratch = serial_in(up, UART_IIR) >> 6;
+
+ DEBUG_AUTOCONF("iir=%d ", scratch);
+
         switch (scratch) {
- case 0:
- up->port.type = PORT_16450;
- break;
- case 1:
- up->port.type = PORT_UNKNOWN;
- break;
- case 2:
- up->port.type = PORT_16550;
- break;
- case 3:
- up->port.type = PORT_16550A;
- break;
- }
- if (up->port.type == PORT_16550A) {
- /* Check for Startech UART's */
- serial_outp(up, UART_LCR, UART_LCR_DLAB);
- if (serial_in(up, UART_EFR) == 0) {
- up->port.type = PORT_16650;
- } else {
- serial_outp(up, UART_LCR, 0xBF);
- if (serial_in(up, UART_EFR) == 0)
- autoconfig_startech_uarts(up);
- }
- }
- if (up->port.type == PORT_16550A) {
- /* Check for TI 16750 */
- serial_outp(up, UART_LCR, save_lcr | UART_LCR_DLAB);
- serial_outp(up, UART_FCR,
- UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
- scratch = serial_in(up, UART_IIR) >> 5;
- if (scratch == 7) {
- /*
- * If this is a 16750, and not a cheap UART
- * clone, then it should only go into 64 byte
- * mode if the UART_FCR7_64BYTE bit was set
- * while UART_LCR_DLAB was latched.
- */
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
- serial_outp(up, UART_LCR, 0);
- serial_outp(up, UART_FCR,
- UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
- scratch = serial_in(up, UART_IIR) >> 5;
- if (scratch == 6)
- up->port.type = PORT_16750;
- }
- serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+ case 0:
+ autoconfig_8250(up);
+ break;
+ case 1:
+ up->port.type = PORT_UNKNOWN;
+ break;
+ case 2:
+ up->port.type = PORT_16550;
+ break;
+ case 3:
+ autoconfig_16550a(up);
+ break;
         }
+
 #if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
         /*
          * Only probe for RSA ports if we got the region.
@@ -586,17 +644,6 @@
         }
 #endif
         serial_outp(up, UART_LCR, save_lcr);
- if (up->port.type == PORT_16450) {
- scratch = serial_in(up, UART_SCR);
- serial_outp(up, UART_SCR, 0xa5);
- status1 = serial_in(up, UART_SCR);
- serial_outp(up, UART_SCR, 0x5a);
- status2 = serial_in(up, UART_SCR);
- serial_outp(up, UART_SCR, scratch);
-
- if ((status1 != 0xa5) || (status2 != 0x5a))
- up->port.type = PORT_8250;
- }
 
         up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
 
@@ -628,6 +675,7 @@
                                "serial_rsa");
         }
 #endif
+ DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
 }
 
 static void autoconfig_irq(struct uart_8250_port *up)
@@ -638,7 +686,7 @@
         unsigned long irqs;
         int irq;
 
- if (up->port.flags & ASYNC_FOURPORT) {
+ if (up->port.flags & UPF_FOURPORT) {
                 ICP = (up->port.iobase & 0xfe0) | 0x1f;
                 save_ICP = inb_p(ICP);
                 outb_p(0x80, ICP);
@@ -654,7 +702,7 @@
         irqs = probe_irq_on();
         serial_outp(up, UART_MCR, 0);
         udelay (10);
- if (up->port.flags & ASYNC_FOURPORT) {
+ if (up->port.flags & UPF_FOURPORT) {
                 serial_outp(up, UART_MCR,
                             UART_MCR_DTR | UART_MCR_RTS);
         } else {
@@ -673,7 +721,7 @@
         serial_outp(up, UART_MCR, save_mcr);
         serial_outp(up, UART_IER, save_ier);
 
- if (up->port.flags & ASYNC_FOURPORT)
+ if (up->port.flags & UPF_FOURPORT)
                 outb_p(save_ICP, ICP);
 
         up->port.irq = (irq > 0) ? irq : 0;
@@ -839,7 +887,7 @@
         } while (--count > 0);
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(&up->port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(&up->port);
 
         DEBUG_INTR("THRE...");
 
@@ -948,10 +996,26 @@
  * line being stuck active, and, since ISA irqs are edge triggered,
  * no more IRQs will be seen.
  */
+static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
+{
+ spin_lock_irq(&i->lock);
+
+ if (!list_empty(i->head)) {
+ if (i->head == &up->list)
+ i->head = i->head->next;
+ list_del(&up->list);
+ } else {
+ BUG_ON(i->head != &up->list);
+ i->head = NULL;
+ }
+
+ spin_unlock_irq(&i->lock);
+}
+
 static int serial_link_irq_chain(struct uart_8250_port *up)
 {
         struct irq_info *i = irq_lists + up->port.irq;
- int ret, irq_flags = share_irqs ? SA_SHIRQ : 0;
+ int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? SA_SHIRQ : 0;
 
         spin_lock_irq(&i->lock);
 
@@ -967,6 +1031,8 @@
 
                 ret = request_irq(up->port.irq, serial8250_interrupt,
                                   irq_flags, "serial", i);
+ if (ret)
+ serial_do_unlink(i, up);
         }
 
         return ret;
@@ -981,18 +1047,7 @@
         if (list_empty(i->head))
                 free_irq(up->port.irq, i);
 
- spin_lock_irq(&i->lock);
-
- if (!list_empty(i->head)) {
- if (i->head == &up->list)
- i->head = i->head->next;
- list_del(&up->list);
- } else {
- BUG_ON(i->head != &up->list);
- i->head = NULL;
- }
-
- spin_unlock_irq(&i->lock);
+ serial_do_unlink(i, up);
 }
 
 /*
@@ -1058,7 +1113,7 @@
 static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
         struct uart_8250_port *up = (struct uart_8250_port *)port;
- unsigned char mcr = ALPHA_KLUDGE_MCR;
+ unsigned char mcr = 0;
 
         if (mctrl & TIOCM_RTS)
                 mcr |= UART_MCR_RTS;
@@ -1071,6 +1126,8 @@
         if (mctrl & TIOCM_LOOP)
                 mcr |= UART_MCR_LOOP;
 
+ mcr = (mcr & up->mcr_mask) | up->mcr_force;
+
         serial_out(up, UART_MCR, mcr);
 }
 
@@ -1139,7 +1196,7 @@
          * if it is, then bail out, because there's likely no UART
          * here.
          */
- if (!(up->port.flags & ASYNC_BUGGY_UART) &&
+ if (!(up->port.flags & UPF_BUGGY_UART) &&
             (serial_inp(up, UART_LSR) == 0xff)) {
                 printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
                 return -ENODEV;
@@ -1169,7 +1226,7 @@
         serial_outp(up, UART_LCR, UART_LCR_WLEN8);
 
         spin_lock_irqsave(&up->port.lock, flags);
- if (up->port.flags & ASYNC_FOURPORT) {
+ if (up->port.flags & UPF_FOURPORT) {
                 if (!is_real_interrupt(up->port.irq))
                         up->port.mctrl |= TIOCM_OUT1;
         } else
@@ -1190,7 +1247,7 @@
         up->ier = UART_IER_RLSI | UART_IER_RDI;
         serial_outp(up, UART_IER, up->ier);
 
- if (up->port.flags & ASYNC_FOURPORT) {
+ if (up->port.flags & UPF_FOURPORT) {
                 unsigned int icp;
                 /*
                  * Enable interrupts on the AST Fourport board
@@ -1223,7 +1280,7 @@
         serial_outp(up, UART_IER, 0);
 
         spin_lock_irqsave(&up->port.lock, flags);
- if (up->port.flags & ASYNC_FOURPORT) {
+ if (up->port.flags & UPF_FOURPORT) {
                 /* reset interrupts on the AST Fourport board */
                 inb((up->port.iobase & 0xfe0) | 0x1f);
                 up->port.mctrl |= TIOCM_OUT1;
@@ -1604,7 +1661,7 @@
         /*
          * Don't probe for MCA ports on non-MCA machines.
          */
- if (up->port.flags & ASYNC_BOOT_ONLYMCA && !MCA_bus)
+ if (up->port.flags & UPF_BOOT_ONLYMCA && !MCA_bus)
                 return;
 #endif
 
@@ -1704,6 +1761,8 @@
                 up->port.iotype = old_serial_port[i].io_type;
                 up->port.regshift = old_serial_port[i].iomem_reg_shift;
                 up->port.ops = &serial8250_pops;
+ if (share_irqs)
+ up->port.flags |= UPF_SHARE_IRQ;
         }
 }
 
@@ -1714,11 +1773,20 @@
         serial8250_isa_init_ports();
 
         for (i = 0; i < UART_NR; i++) {
- serial8250_ports[i].port.line = i;
- serial8250_ports[i].port.ops = &serial8250_pops;
- init_timer(&serial8250_ports[i].timer);
- serial8250_ports[i].timer.function = serial8250_timeout;
- uart_add_one_port(drv, &serial8250_ports[i].port);
+ struct uart_8250_port *up = &serial8250_ports[i];
+
+ up->port.line = i;
+ up->port.ops = &serial8250_pops;
+ init_timer(&up->timer);
+ up->timer.function = serial8250_timeout;
+
+ /*
+ * ALPHA_KLUDGE_MCR needs to be killed.
+ */
+ up->mcr_mask = ~ALPHA_KLUDGE_MCR;
+ up->mcr_force = ALPHA_KLUDGE_MCR;
+
+ uart_add_one_port(drv, &up->port);
         }
 }
 
@@ -1746,7 +1814,7 @@
         } while ((status & BOTH_EMPTY) != BOTH_EMPTY);
 
         /* Wait up to 1s for flow control if necessary */
- if (up->port.flags & ASYNC_CONS_FLOW) {
+ if (up->port.flags & UPF_CONS_FLOW) {
                 tmout = 1000000;
                 while (--tmout &&
                        ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
@@ -1857,7 +1925,7 @@
 #ifdef CONFIG_DEVFS_FS
         .dev_name = "tts/%d",
 #else
- .dev_name = "ttyS",
+ .dev_name = "ttyS%d",
 #endif
         .major = TTY_MAJOR,
         .minor = 64,
@@ -1881,8 +1949,11 @@
         port.fifosize = req->xmit_fifo_size;
         port.regshift = req->iomem_reg_shift;
         port.iotype = req->io_type;
- port.flags = req->flags | ASYNC_BOOT_AUTOCONF;
+ port.flags = req->flags | UPF_BOOT_AUTOCONF;
         port.line = line;
+
+ if (share_irqs)
+ port.flags |= UPF_SHARE_IRQ;
 
         if (HIGH_BITS_OFFSET)
                 port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET;
diff -Nru a/drivers/serial/8250_cs.c b/drivers/serial/8250_cs.c
--- a/drivers/serial/8250_cs.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/8250_cs.c Sat Nov 2 16:55:01 2002
@@ -41,6 +41,7 @@
 #include <linux/timer.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
+#include <linux/serial_core.h>
 #include <linux/major.h>
 #include <linux/workqueue.h>
 #include <asm/io.h>
@@ -306,7 +307,7 @@
         memset(&serial, 0, sizeof (serial));
         serial.port = port;
         serial.irq = irq;
- serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
+ serial.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ;
         line = register_serial(&serial);
         if (line < 0) {
                 printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
diff -Nru a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
--- a/drivers/serial/8250_pci.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/8250_pci.c Sat Nov 2 16:55:01 2002
@@ -11,7 +11,7 @@
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License.
  *
- * $Id: 8250_pci.c,v 1.24 2002/07/29 14:39:56 rmk Exp $
+ * $Id: 8250_pci.c,v 1.28 2002/11/02 11:14:18 rmk Exp $
  */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/serial.h>
-
 #include <linux/serialP.h>
 
 #include <asm/bitops.h>
@@ -55,14 +54,19 @@
         int line[0];
 };
 
+/*
+ * init_fn returns:
+ * > 0 - number of ports
+ * = 0 - use board->num_ports
+ * < 0 - error
+ */
 struct pci_board {
         int flags;
         int num_ports;
         int base_baud;
         int uart_offset;
         int reg_shift;
- int (*init_fn)(struct pci_dev *dev, struct pci_board *board,
- int enable);
+ int (*init_fn)(struct pci_dev *dev, int enable);
         int first_uart_offset;
 };
 
@@ -201,8 +205,7 @@
  * seems to be mainly needed on card using the PLX which also use I/O
  * mapped memory.
  */
-static int __devinit
-pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_plx9050_fn(struct pci_dev *dev, int enable)
 {
         u8 *p, irq_config = 0;
 
@@ -264,8 +267,7 @@
 #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
 #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
 
-static int __devinit
-pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_siig10x_fn(struct pci_dev *dev, int enable)
 {
         u16 data, *p;
 
@@ -296,8 +298,7 @@
 #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
 #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
 
-static int __devinit
-pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_siig20x_fn(struct pci_dev *dev, int enable)
 {
         u8 data;
 
@@ -318,8 +319,7 @@
 }
 
 /* Added for EKF Intel i960 serial boards */
-static int __devinit
-pci_inteli960ni_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_inteli960ni_fn(struct pci_dev *dev, int enable)
 {
         unsigned long oldval;
 
@@ -378,8 +378,7 @@
         { 0, 0 }
 };
 
-static int __devinit
-pci_timedia_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_timedia_fn(struct pci_dev *dev, int enable)
 {
         int i, j;
         unsigned short *ids;
@@ -389,12 +388,9 @@
 
         for (i = 0; timedia_data[i].num; i++) {
                 ids = timedia_data[i].ids;
- for (j = 0; ids[j]; j++) {
- if (pci_get_subdevice(dev) == ids[j]) {
- board->num_ports = timedia_data[i].num;
- return 0;
- }
- }
+ for (j = 0; ids[j]; j++)
+ if (pci_get_subdevice(dev) == ids[j])
+ return timedia_data[i].num;
         }
         return 0;
 }
@@ -406,9 +402,10 @@
  * and Keystone have one Diva chip with 3 UARTs. Some later machines have
  * one Diva chip, but it has been expanded to 5 UARTs.
  */
-static int __devinit
-pci_hp_diva(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_hp_diva(struct pci_dev *dev, int enable)
 {
+ int rc = 0;
+
         if (!enable)
                 return 0;
 
@@ -417,25 +414,24 @@
         case PCI_DEVICE_ID_HP_DIVA_HALFDOME:
         case PCI_DEVICE_ID_HP_DIVA_KEYSTONE:
         case PCI_DEVICE_ID_HP_DIVA_EVEREST:
- board->num_ports = 3;
+ rc = 3;
                 break;
         case PCI_DEVICE_ID_HP_DIVA_TOSCA2:
- board->num_ports = 2;
+ rc = 2;
                 break;
         case PCI_DEVICE_ID_HP_DIVA_MAESTRO:
- board->num_ports = 4;
+ rc = 4;
                 break;
         case PCI_DEVICE_ID_HP_DIVA_POWERBAR:
- board->num_ports = 1;
+ rc = 1;
                 break;
         }
 
- return 0;
+ return rc;
 }
 
 
-static int __devinit
-pci_xircom_fn(struct pci_dev *dev, struct pci_board *board, int enable)
+static int __devinit pci_xircom_fn(struct pci_dev *dev, int enable)
 {
         __set_current_state(TASK_UNINTERRUPTIBLE);
         schedule_timeout(HZ/10);
@@ -579,8 +575,11 @@
                 0x400, 7, pci_plx9050_fn },
         { SPCI_FL_BASE2, 4, 921600, /* pbn_plx_romulus */
                 0x20, 2, pci_plx9050_fn, 0x03 },
- /* This board uses the size of PCI Base region 0 to
- * signal now many ports are available */
+
+ /*
+ * This board uses the size of PCI Base region 0 to
+ * signal now many ports are available
+ */
         { SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, /* pbn_oxsemi */
         { SPCI_FL_BASE_TABLE, 1, 921600, /* pbn_timedia */
                 0, 0, pci_timedia_fn },
@@ -645,9 +644,9 @@
          * later?)
          */
         if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
- ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
+ ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
             (dev->class & 0xff) > 6)
- return 1;
+ return -ENODEV;
 
         for (i = 0; i < 6; i++) {
                 if (IS_PCI_REGION_IOPORT(dev, i)) {
@@ -667,20 +666,31 @@
                 board->flags = first_port;
                 return 0;
         }
- return 1;
+ return -ENODEV;
+}
+
+static inline int
+serial_pci_matches(struct pci_board *board, int index)
+{
+ return
+ board->base_baud == pci_boards[index].base_baud &&
+ board->num_ports == pci_boards[index].num_ports &&
+ board->uart_offset == pci_boards[index].uart_offset &&
+ board->reg_shift == pci_boards[index].reg_shift &&
+ board->first_uart_offset == pci_boards[index].first_uart_offset;
 }
 
 /*
- * return an error code to refuse.
- *
- * serial_struct is 60 bytes.
+ * Probe one serial board. Unfortunately, there is no rhyme nor reason
+ * to the arrangement of serial ports on a PCI card.
  */
-static int __devinit pci_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
+static int __devinit
+pci_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
 {
         struct serial_private *priv;
         struct pci_board *board, tmp;
         struct serial_struct serial_req;
- int base_baud, rc, k;
+ int base_baud, rc, nr_ports, i;
 
         if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {
                 printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",
@@ -694,67 +704,98 @@
         if (rc)
                 return rc;
 
- if (ent->driver_data == pbn_default &&
- serial_pci_guess_board(dev, board)) {
- pci_disable_device(dev);
- return -ENODEV;
- } else if (serial_pci_guess_board(dev, &tmp) == 0) {
- printk(KERN_INFO "Redundant entry in serial pci_table. "
- "Please send the output of\n"
- "lspci -vv, this message (%d,%d,%d,%d)\n"
- "and the manufacturer and name of "
- "serial board or modem board\n"
- "to serial-pci-info@lists.sourceforge.net.\n",
- dev->vendor, dev->device,
- pci_get_subvendor(dev), pci_get_subdevice(dev));
+ if (ent->driver_data == pbn_default) {
+ /*
+ * Use a copy of the pci_board entry for this;
+ * avoid changing entries in the table.
+ */
+ memcpy(&tmp, board, sizeof(struct pci_board));
+ board = &tmp;
+
+ /*
+ * We matched one of our class entries. Try to
+ * determine the parameters of this board.
+ */
+ rc = serial_pci_guess_board(dev, board);
+ if (rc)
+ goto disable;
+ } else {
+ /*
+ * We matched an explicit entry. If we are able to
+ * detect this boards settings with our heuristic,
+ * then we no longer need this entry.
+ */
+ rc = serial_pci_guess_board(dev, &tmp);
+ if (rc == 0 && serial_pci_matches(board, pbn_default)) {
+ printk(KERN_INFO
+ "Redundant entry in serial pci_table. Please send the output\n"
+ "of lspci -vv, this message (0x%04x,0x%04x,0x%04x,0x%04x),\n"
+ "the manufacturer and name of serial board or modem board to\n"
+ "rmk@arm.linux.org.uk.\n",
+ dev->vendor, dev->device,
+ pci_get_subvendor(dev), pci_get_subdevice(dev));
+ }
         }
 
- priv = kmalloc(sizeof(struct serial_private) +
- sizeof(unsigned int) * board->num_ports,
- GFP_KERNEL);
- if (!priv) {
- pci_disable_device(dev);
- return -ENOMEM;
- }
+ nr_ports = board->num_ports;
 
         /*
- * Run the initialization function, if any
+ * Run the initialization function, if any. The initialization
+ * function returns:
+ * <0 - error
+ * 0 - use board->num_ports
+ * >0 - number of ports
          */
         if (board->init_fn) {
- rc = board->init_fn(dev, board, 1);
- if (rc != 0) {
- pci_disable_device(dev);
- kfree(priv);
- return rc;
- }
+ rc = board->init_fn(dev, 1);
+ if (rc < 0)
+ goto disable;
+
+ if (rc)
+ nr_ports = rc;
+ }
+
+ priv = kmalloc(sizeof(struct serial_private) +
+ sizeof(unsigned int) * nr_ports,
+ GFP_KERNEL);
+ if (!priv) {
+ rc = -ENOMEM;
+ goto deinit;
         }
 
         base_baud = board->base_baud;
         if (!base_baud)
                 base_baud = BASE_BAUD;
         memset(&serial_req, 0, sizeof(serial_req));
- for (k = 0; k < board->num_ports; k++) {
- serial_req.irq = get_pci_irq(dev, board, k);
- if (get_pci_port(dev, board, &serial_req, k))
+ for (i = 0; i < nr_ports; i++) {
+ serial_req.irq = get_pci_irq(dev, board, i);
+ if (get_pci_port(dev, board, &serial_req, i))
                         break;
 #ifdef SERIAL_DEBUG_PCI
- printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
+ printk("Setup PCI port: port %x, irq %d, type %d\n",
                        serial_req.port, serial_req.irq, serial_req.io_type);
 #endif
                 serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
                 serial_req.baud_base = base_baud;
                 
- priv->line[k] = register_serial(&serial_req);
- if (priv->line[k] < 0)
+ priv->line[i] = register_serial(&serial_req);
+ if (priv->line[i] < 0)
                         break;
         }
 
         priv->board = board;
- priv->nr = k;
+ priv->nr = i;
 
         pci_set_drvdata(dev, priv);
 
         return 0;
+
+ deinit:
+ if (board->init_fn)
+ board->init_fn(dev, 0);
+ disable:
+ pci_disable_device(dev);
+ return rc;
 }
 
 static void __devexit pci_remove_one(struct pci_dev *dev)
@@ -769,7 +810,7 @@
                         unregister_serial(priv->line[i]);
 
                 if (priv->board->init_fn)
- priv->board->init_fn(dev, priv->board, 0);
+ priv->board->init_fn(dev, 0);
 
                 pci_disable_device(dev);
 
@@ -1160,18 +1201,23 @@
                 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                 pbn_dci_pccom8 },
 
+ /*
+ * These entries match devices with class
+ * COMMUNICATION_SERIAL, COMMUNICATION_MODEM
+ * or COMMUNICATION_MULTISERIAL
+ */
         { PCI_ANY_ID, PCI_ANY_ID,
                 PCI_ANY_ID, PCI_ANY_ID,
                 PCI_CLASS_COMMUNICATION_SERIAL << 8,
- 0xffff00, },
+ 0xffff00, pbn_default },
         { PCI_ANY_ID, PCI_ANY_ID,
                 PCI_ANY_ID, PCI_ANY_ID,
                 PCI_CLASS_COMMUNICATION_MODEM << 8,
- 0xffff00, },
+ 0xffff00, pbn_default },
         { PCI_ANY_ID, PCI_ANY_ID,
                 PCI_ANY_ID, PCI_ANY_ID,
                 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
- 0xffff00, },
+ 0xffff00, pbn_default },
         { 0, }
 };
 
diff -Nru a/drivers/serial/amba.c b/drivers/serial/amba.c
--- a/drivers/serial/amba.c Sat Nov 2 16:55:00 2002
+++ b/drivers/serial/amba.c Sat Nov 2 16:55:00 2002
@@ -245,7 +245,7 @@
         } while (--count > 0);
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(port);
 
         if (uart_circ_empty(xmit))
                 ambauart_stop_tx(port);
@@ -706,11 +706,7 @@
 static struct uart_driver amba_reg = {
         .owner = THIS_MODULE,
         .driver_name = "ttyAM",
-#ifdef CONFIG_DEVFS_FS
         .dev_name = "ttyAM%d",
-#else
- .dev_name = "ttyAM",
-#endif
         .major = SERIAL_AMBA_MAJOR,
         .minor = SERIAL_AMBA_MINOR,
         .nr = UART_NR,
diff -Nru a/drivers/serial/anakin.c b/drivers/serial/anakin.c
--- a/drivers/serial/anakin.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/anakin.c Sat Nov 2 16:55:01 2002
@@ -161,7 +161,7 @@
         anakin_transmit_buffer(port);
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(port);
 }
 
 static void
diff -Nru a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
--- a/drivers/serial/clps711x.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/clps711x.c Sat Nov 2 16:55:01 2002
@@ -50,14 +50,12 @@
 #define UART_NR 2
 
 #ifndef CONFIG_SERIAL_CLPS711X_OLD_NAME
-#define SERIAL_CLPS711X_NAME "ttyCL"
 #define SERIAL_CLPS711X_MAJOR 204
 #define SERIAL_CLPS711X_MINOR 40
 #define SERIAL_CLPS711X_NR UART_NR
 
 #else
 #warning The old names/device number for this driver if compatabity is needed
-#define SERIAL_CLPS711X_NAME "ttyAM"
 #define SERIAL_CLPS711X_MAJOR 204
 #define SERIAL_CLPS711X_MINOR 16
 #define SERIAL_CLPS711X_NR UART_NR
@@ -209,7 +207,7 @@
         } while (--count > 0);
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(port);
 
         if (uart_circ_empty(xmit))
                 clps711xuart_stop_tx(port);
@@ -545,7 +543,7 @@
 }
 
 static struct console clps711x_console = {
- .name = SERIAL_CLPS711X_NAME,
+ .name = "ttyCL",
         .write = clps711xuart_console_write,
         .device = clps711xuart_console_device,
         .setup = clps711xuart_console_setup,
@@ -565,12 +563,7 @@
 
 static struct uart_driver clps711x_reg = {
         .driver_name = "ttyCL",
-#ifdef CONFIG_DEVFS_FS
- .dev_name = SERIAL_CLPS711X_NAME,
-#else
- .dev_name = SERIAL_CLPS711X_NAME,
-#endif
-
+ .dev_name = "ttyCL%d",
         .major = SERIAL_CLPS711X_MAJOR,
         .minor = SERIAL_CLPS711X_MINOR,
         .nr = UART_NR,
diff -Nru a/drivers/serial/core.c b/drivers/serial/core.c
--- a/drivers/serial/core.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/core.c Sat Nov 2 16:55:01 2002
@@ -65,11 +65,9 @@
  * This routine is used by the interrupt handler to schedule processing in
  * the software interrupt portion of the driver.
  */
-void uart_event(struct uart_port *port, int event)
+void uart_write_wakeup(struct uart_port *port)
 {
         struct uart_info *info = port->info;
-
- set_bit(0, &info->event);
         tasklet_schedule(&info->tlet);
 }
 
@@ -112,13 +110,12 @@
         struct tty_struct *tty;
 
         tty = info->tty;
- if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event))
- return;
-
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
- wake_up_interruptible(&tty->write_wait);
+ if (tty) {
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ tty->ldisc.write_wakeup)
+ tty->ldisc.write_wakeup(tty);
+ wake_up_interruptible(&tty->write_wait);
+ }
 }
 
 static inline void
@@ -1981,7 +1978,8 @@
 static inline void
 uart_report_port(struct uart_driver *drv, struct uart_port *port)
 {
- printk("%s%d at ", drv->dev_name, port->line);
+ printk(drv->dev_name, port->line);
+ printk(" at ");
         switch (port->iotype) {
         case UPIO_PORT:
                 printk("I/O 0x%x", port->iobase);
@@ -2005,7 +2003,6 @@
         state->port = port;
 
         spin_lock_init(&port->lock);
- port->type = PORT_UNKNOWN;
         port->cons = drv->cons;
         port->info = state->info;
 
@@ -2022,8 +2019,10 @@
         flags = UART_CONFIG_TYPE;
         if (port->flags & UPF_AUTO_IRQ)
                 flags |= UART_CONFIG_IRQ;
- if (port->flags & UPF_BOOT_AUTOCONF)
+ if (port->flags & UPF_BOOT_AUTOCONF) {
+ port->type = PORT_UNKNOWN;
                 port->ops->config_port(port, flags);
+ }
 
         /*
          * Register the port whether it's detected or not. This allows
@@ -2439,8 +2438,9 @@
         struct uart_state *state;
 
         if (line < 0 || line >= drv->nr) {
- printk(KERN_ERR "Attempt to unregister %s%d\n",
- drv->dev_name, line);
+ printk(KERN_ERR "Attempt to unregister ");
+ printk(drv->dev_name, line);
+ printk("\n");
                 return;
         }
 
@@ -2453,7 +2453,7 @@
         up(&port_sem);
 }
 
-EXPORT_SYMBOL(uart_event);
+EXPORT_SYMBOL(uart_write_wakeup);
 EXPORT_SYMBOL(uart_register_driver);
 EXPORT_SYMBOL(uart_unregister_driver);
 EXPORT_SYMBOL(uart_register_port);
diff -Nru a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
--- a/drivers/serial/sa1100.c Sat Nov 2 16:55:00 2002
+++ b/drivers/serial/sa1100.c Sat Nov 2 16:55:00 2002
@@ -305,7 +305,7 @@
         }
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(&sport->port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(&sport->port);
 
         if (uart_circ_empty(xmit))
                 sa1100_stop_tx(&sport->port, 0);
@@ -661,7 +661,7 @@
 void __init sa1100_register_uart(int idx, int port)
 {
         if (idx >= NR_PORTS) {
- printk(KERN_ERR __FUNCTION__ ": bad index number %d\n", idx);
+ printk(KERN_ERR "%s: bad index number %d\n", __FUNCTION__, idx);
                 return;
         }
 
@@ -688,7 +688,7 @@
                 break;
 
         default:
- printk(KERN_ERR __FUNCTION__ ": bad port number %d\n", port);
+ printk(KERN_ERR "%s: bad port number %d\n", __FUNCTION__, port);
         }
 }
 
@@ -827,11 +827,7 @@
 static struct uart_driver sa1100_reg = {
         .owner = THIS_MODULE,
         .driver_name = "ttySA",
-#ifdef CONFIG_DEVFS_FS
         .dev_name = "ttySA%d",
-#else
- .dev_name = "ttySA",
-#endif
         .major = SERIAL_SA1100_MAJOR,
         .minor = MINOR_START,
         .nr = NR_PORTS,
diff -Nru a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
--- a/drivers/serial/sunsab.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/sunsab.c Sat Nov 2 16:55:01 2002
@@ -266,7 +266,7 @@
         writeb(SAB82532_CMDR_XF, &up->regs->w.cmdr);
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(&up->port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(&up->port);
 
         if (uart_circ_empty(xmit))
                 sunsab_stop_tx(&up->port, 0);
@@ -843,7 +843,7 @@
 #ifdef CONFIG_DEVFS_FS
         .dev_name = "tts/%d",
 #else
- .dev_name = "ttyS",
+ .dev_name = "ttyS%d",
 #endif
         .major = TTY_MAJOR,
 };
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c Sat Nov 2 16:55:00 2002
+++ b/drivers/serial/sunsu.c Sat Nov 2 16:55:01 2002
@@ -431,7 +431,7 @@
         } while (--count > 0);
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(&up->port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(&up->port);
 
         if (uart_circ_empty(xmit))
                 sunsu_stop_tx(&up->port, 0);
@@ -1262,7 +1262,7 @@
 #ifdef CONFIG_DEVFS_FS
         .dev_name = "tts/%d",
 #else
- .dev_name = "ttyS",
+ .dev_name = "ttyS%d",
 #endif
         .major = TTY_MAJOR,
 };
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/sunzilog.c Sat Nov 2 16:55:01 2002
@@ -523,7 +523,7 @@
         up->port.icount.tx++;
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(&up->port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(&up->port);
 
         if (!uart_circ_empty(xmit))
                 return;
@@ -1003,7 +1003,7 @@
 #ifdef CONFIG_DEVFS_FS
         .dev_name = "ttyS%d",
 #else
- .dev_name = "ttyS",
+ .dev_name = "ttyS%d",
 #endif
         .major = TTY_MAJOR,
 };
diff -Nru a/drivers/serial/uart00.c b/drivers/serial/uart00.c
--- a/drivers/serial/uart00.c Sat Nov 2 16:55:01 2002
+++ b/drivers/serial/uart00.c Sat Nov 2 16:55:01 2002
@@ -215,7 +215,7 @@
         } while (--count > 0);
 
         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_event(port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(port);
 
         if (uart_circ_empty(xmit))
                 uart00_stop_tx(port, 0);
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h Sat Nov 2 16:55:00 2002
+++ b/include/linux/serial_core.h Sat Nov 2 16:55:00 2002
@@ -154,6 +154,7 @@
         unsigned int flags;
 
 #define UPF_HUP_NOTIFY (1 << 0)
+#define UPF_FOURPORT (1 << 1)
 #define UPF_SAK (1 << 2)
 #define UPF_SPD_MASK (0x1030)
 #define UPF_SPD_HI (0x0010)
@@ -167,6 +168,9 @@
 #define UPF_LOW_LATENCY (1 << 13)
 #define UPF_BUGGY_UART (1 << 14)
 #define UPF_AUTOPROBE (1 << 15)
+#define UPF_BOOT_ONLYMCA (1 << 22)
+#define UPF_CONS_FLOW (1 << 23)
+#define UPF_SHARE_IRQ (1 << 24)
 #define UPF_BOOT_AUTOCONF (1 << 28)
 #define UPF_RESOURCES (1 << 30)
 #define UPF_IOREMAP (1 << 31)
@@ -247,8 +251,6 @@
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
 
-#define EVT_WRITE_WAKEUP 0
-
 struct module;
 struct tty_driver;
 
@@ -269,7 +271,7 @@
         struct tty_driver *tty_driver;
 };
 
-void uart_event(struct uart_port *port, int event);
+void uart_write_wakeup(struct uart_port *port);
 struct uart_port *uart_get_console(struct uart_port *ports, int nr,
                                    struct console *c);
 void uart_parse_options(char *options, int *baud, int *parity, int *bits,
@@ -380,7 +382,7 @@
                         if (status) {
                                 tty->hw_stopped = 0;
                                 port->ops->start_tx(port, 0);
- uart_event(port, EVT_WRITE_WAKEUP);
+ uart_write_wakeup(port);
                         }
                 } else {
                         if (!status) {

-- 
Russell King (rmk@arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Nov 07 2002 - 22:00:24 EST